Lors du diagnostic des requêtes SQL Server 2008 R2 avec une mauvaise estimation de la cardinalité (malgré une indexation simple, des statistiques à jour, etc.) et donc des plans de requête médiocres, j'ai trouvé un article de la base de connaissances peut-être lié: CORRECTIF: performances médiocres lorsque vous exécutez une requête qui contient des prédicats ET corrélés dans SQL Server 2008 ou SQL Server 2008 R2 ou SQL Server 2012
Je peux deviner ce que l'article de la base de connaissances entend par "corrélé", par exemple le prédicat n ° 2 et le prédicat n ° 1 ciblent largement les mêmes lignes.
Mais je ne sais pas comment SQL Server connaît ces corrélations. Une table a-t-elle besoin d'un index multi-colonnes contenant des colonnes des deux prédicats? SQL utilise-t-il des statistiques pour vérifier si les valeurs d'une colonne sont corrélées à une autre? Ou une autre méthode est-elle utilisée?
Je pose cette question pour deux raisons:
- pour déterminer laquelle de mes tables et requêtes pourrait être améliorée à l'aide de ce correctif
- savoir ce que je dois faire en indexation, statistiques, etc. pour affecter # 1
la source
Statistics objects on multiple columns also store statistical information about the correlation of values among the columns
Réponses:
Considérez le simple plan de requête et d'exécution AdventureWorks illustré ci-dessous. La requête contient des prédicats liés à
AND
. L'estimation de la cardinalité de l'optimiseur est de 41 211 lignes:Utilisation de statistiques par défaut
Étant donné que les statistiques sur une seule colonne, l'optimiseur produit cette estimation en estimant séparément la cardinalité de chaque prédicat et en multipliant les sélectivités résultantes. Cette heuristique suppose que les prédicats sont complètement indépendants.
La division de la requête en deux parties facilite le calcul:
Le tableau Historique des transactions contient 113 443 lignes au total, donc l'estimation de 68 336,4 représente une sélectivité de 68336,4 / 113443 = 0,60238533 pour ce prédicat. Cette estimation est obtenue à l'aide des informations d'histogramme de la
TransactionID
colonne et des valeurs constantes spécifiées dans la requête.Ce prédicat a une sélectivité estimée de 68413,0 / 113443 = 0,60306056 . Encore une fois, il est calculé à partir des valeurs constantes du prédicat et de l'histogramme de l'
TransactionDate
objet statistique.En supposant que les prédicats sont complètement indépendants, nous pouvons estimer la sélectivité des deux prédicats ensemble en les multipliant ensemble. L'estimation de cardinalité finale est obtenue en multipliant la sélectivité résultante par les 113 443 lignes du tableau de base:
Après l'arrondi, il s'agit de l'estimation 41 211 observée dans la requête d'origine (l'optimiseur utilise également des mathématiques à virgule flottante en interne).
Pas une bonne estimation
Les colonnes
TransactionID
etTransactionDate
ont une corrélation étroite dans l'ensemble de données AdventureWorks (comme le font souvent les clés et les colonnes de date à augmentation monotone). Cette corrélation signifie que l'hypothèse d'indépendance est violée. Par conséquent, le plan de requête post-exécution affiche 68 095 lignes au lieu des 41 211 estimés:Indicateur de trace 4137
L'activation de cet indicateur de trace modifie l'heuristique utilisée pour combiner les prédicats. Au lieu de supposer une indépendance complète, l'optimiseur considère que les sélectivités des deux prédicats sont suffisamment proches pour être corrélées:
Rappelons que le
TransactionID
prédicat à lui seul estimait 68 336,4 lignes et leTransactionDate
prédicat à lui seul estimait 68 413 lignes. L'optimiseur a choisi la plus basse de ces deux estimations plutôt que de multiplier les sélectivités.Il s'agit bien sûr d'une heuristique différente, mais qui peut aider à améliorer les estimations des requêtes avec des
AND
prédicats corrélés . Chaque prédicat est considéré pour une éventuelle corrélation, et d'autres ajustements sont effectués lorsque de nombreusesAND
clauses sont impliquées, mais cet exemple sert à en montrer les bases.Statistiques multi-colonnes
Ceux-ci peuvent aider dans les requêtes avec corrélations, mais les informations d'histogramme sont toujours basées uniquement sur la première colonne des statistiques. Les statistiques multi-colonnes candidates suivantes diffèrent donc de manière importante:
En prenant un seul de ceux-ci, nous pouvons voir que la seule information supplémentaire est les niveaux supplémentaires de la densité «tous». L'histogramme ne contient toujours que des informations détaillées sur la
TransactionDate
colonne.Avec ces statistiques multi-colonnes en place ...
... le plan d'exécution affiche une estimation qui est exactement la même que lorsque seules les statistiques sur une seule colonne étaient disponibles:
la source