Résolution des problèmes liés à la médiocrité des performances des requêtes : estimation de la cardinalité
L'optimiseur de requête dans SQL Server est basé sur les coûts. Cela signifie qu'il sélectionne des plans de requête dont l'exécution présente le plus faible coût de traitement estimé. L'optimiseur de requête détermine le coût d'exécution d'un plan de requête à partir de deux facteurs principaux :
Le nombre total de lignes traitées à chaque niveau d'un plan de requête, appelé « cardinalité du plan »
Le modèle de coût de l'algorithme imposé par les opérateurs utilisés dans la requête
Le premier facteur, la cardinalité, est utilisé comme paramètre d'entrée du deuxième facteur, le modèle de coût. Par conséquent, une amélioration de la cardinalité aboutit à de meilleurs coûts estimés, ce qui permet d'obtenir des plans d'exécution plus rapides.
SQL Server évalue les cardinalités essentiellement à partir d'histogrammes générés lors de la création manuelle ou automatique d'index ou de statistiques. Parfois, SQL Server utilise également des informations de contraintes et des réécritures logiques de requêtes pour déterminer la cardinalité.
Dans les cas suivants, SQL Server ne peut pas calculer les cardinalités avec précision. Il en résulte des calculs de coût imprécis pouvant aboutir à des plans de requête non optimisés. La non-utilisation de ces constructions dans les requêtes peut améliorer les performances de celles-ci. Parfois, d'autres formulations de requête ou d'autres mesures sont possibles, auquel cas elles sont soulignées.
Les requêtes avec prédicats qui utilisent des opérateurs de comparaison entre différentes colonnes de la même table.
Les requêtes avec prédicats qui utilisent des opérateurs, dans l'une des situations suivantes :
Il n'existe pas de statistiques sur les colonnes utilisées de chaque côté des opérateurs.
La répartition des valeurs dans les statistiques n'est pas uniforme, mais la requête recherche un ensemble de valeurs hautement sélectif. Cette situation se vérifie notamment si l'opérateur est tout opérateur autre que celui d'égalité (=).
Le prédicat utilise l'opérateur de comparaison de non-égalité (!=) ou l'opérateur logique NOT.
Les requêtes qui utilisent n'importe quelle fonction SQL Server intégrée ou une fonction scalaire définie par l'utilisateur dont l'argument n'est pas une valeur constante.
Les requêtes qui impliquent la jointure de colonnes par le biais d'opérateurs de concaténation de chaînes ou arithmétiques.
Les requêtes qui comparent des variables dont les valeurs ne sont pas connues au moment de la compilation et de l'optimisation des requêtes.
Vous pouvez avoir recours aux mesures suivantes pour essayer d'améliorer les performances de ces types de requêtes :
Créez des index ou des statistiques utiles sur les colonnes impliquées dans la requête. Pour plus d'informations, consultez Conception d'index et Utilisation des statistiques pour améliorer les performances des requêtes.
Pensez à utiliser des colonnes calculées et à réécrire la requête si celle-ci recourt à des opérateurs arithmétiques ou de comparaison pour comparer ou combiner au moins deux colonnes. Par exemple, la requête suivante compare les valeurs de deux colonnes :
SELECT * FROM MyTable WHERE MyTable.Col1 > MyTable.Col2
Vous pouvez améliorer les performances en ajoutant une colonne calculée Col3 à MyTable qui calcule la différence entre Col1 et Col2 (Col1 moins Col2). Ensuite, réécrivez la requête :
SELECT * FROM MyTable WHERE Col3 > 0
Vous pouvez probablement améliorer davantage les performances en créant un index sur MyTable.Col3.