Au cours de l'enquête sur une requête lente, il est apparu que le plan d'exécution était exceptionnellement sous-optimal (une boucle imbriquée effectuant 9 millions d'exécutions d'une recherche où le nombre estimé d'exécutions était de 1). Après avoir confirmé que certaines statistiques pertinentes étaient en fait obsolètes, j'ai reconstruit les statistiques et le problème de performance est effectivement résolu.
Les statistiques de mise à jour automatique sont activées dans cette base de données (activée par défaut). Je comprends qu'il existe un seuil pour les mises à jour automatiques des statistiques basé sur 20% + 500 modifications de ligne (mise à jour / insertion / suppressions). Ce seuil semble avoir été dépassé dans une large mesure sur plusieurs index, en tant que tel, il semble qu'il y ait (A) un problème avec les mises à jour automatiques ou (B) La stratégie de mise à jour comporte plus que ce que j'ai pu trouver en ligne Documentation.
J'apprécie qu'une tâche planifiée puisse être mise en place pour mettre à jour les statistiques et c'est probablement l'approche que nous adopterons si aucune autre solution ne peut être trouvée, mais cela nous laisse perplexe quant à la raison pour laquelle un si grand nombre de modifications ne déclencherait pas de mise à jour automatique pour certaines statistiques - comprendre pourquoi cela pourrait nous aider à décider quelles statistiques doivent être mises à jour par une tâche planifiée.
Quelques notes supplémentaires:
1) Le problème a été noté dans une base de données où les données sont créées par un test de charge et en tant que telle une grande quantité de données est ajoutée dans un court laps de temps, donc si la mise à jour automatique s'est produite périodiquement (par exemple une fois par jour à la plupart), cela peut expliquer certains des comportements observés. De plus, nos tests de charge ont tendance à stresser fortement la base de données, donc je me demande si SQL reporte les mises à jour des statistiques alors qu'il y a une forte charge (et par conséquent ne met pas à jour les statistiques pour une raison quelconque).
2) En essayant de recréer ce problème avec un script de test contenant les instructions INSERT, SELECT et DELETE successives, le problème ne s'est pas produit. Je me demande si la distinction ici est que ces instructions affectent chacune plusieurs lignes par instruction SQL, alors que notre script de test de charge aura tendance à insérer des lignes individuellement.
3) La base de données en question est définie sur le modèle de récupération «simple».
Quelques liens pertinents:
- Liste de contrôle pour l'analyse des requêtes à exécution lente
- Utilisation des statistiques pour améliorer les performances des requêtes
J'ai également soulevé ce problème via Microsoft Connect:
MISE À JOUR 2011-06-30:
Après une enquête plus approfondie, je pense que les statistiques qui sont obsolètes au-delà des niveaux de seuils (par exemple 500 lignes + 20%) sont des statistiques qui ne sont pas utilisées par la requête problématique, elles seront donc probablement mises à jour lorsqu'une requête est exécutée cela les oblige. Pour les statistiques qui sont utilisés par la requête, ceux - ci sont mis à jour régulièrement. Le problème restant est alors que ces statistiques sont extrêmement trompeuses pour l'optimiseur de plan de requête après seulement quelques insertions (par exemple, provoquant les 9 millions de recherches susmentionnées où le nombre estimé était 1).
Mon intuition en ce moment est que le problème est lié à un mauvais choix de clé primaire, la clé est un identifiant unique créé à l'aide de NEWID (), et cela crée donc un index très fragmenté très rapidement - d'autant plus que le facteur de remplissage par défaut dans SQL Le serveur est à 100%. Mon intuition est que cela entraîne en quelque sorte des statistiques trompeuses après relativement peu d'insertions de lignes - moins que le seuil de recalcul des statistiques. Tout cela n'est peut-être pas un problème car j'ai généré beaucoup de données sans reconstruire les index à mi-chemin, donc les mauvaises statistiques peuvent être la conséquence de la fragmentation d'indice très élevée qui en résulte. Je pense que je dois ajouter des cycles de maintenance SQL Server dans mon test de charge pour avoir une meilleure idée des performances sur un système réel sur de longues périodes.
MISE À JOUR 2012-01-10:
Un autre facteur à considérer. Deux indicateurs de trace ont été ajoutés à SQL Server 2005 (et semblent être toujours présents en 2008) pour remédier à des lacunes spécifiques liées à l'occurrence de statistiques obsolètes et / ou trompeuses. Les drapeaux en question sont:
DBCC TRACEON(2389)
DBCC TRACEON(2390)
MSDN: WebLog d'Ian Jose: Touches ascendantes et statistiques statistiques à correction rapide automatique sur les colonnes ascendantes, Fabiano Amorim
Vous devez bien sûr être très prudent lorsque vous décidez d'activer ces indicateurs car ils peuvent avoir des effets néfastes.