J'ai une requête qui joint quelques tables et fonctionne assez mal - les estimations de ligne sont très éloignées (1000 fois) et la jointure de boucles imbriquées est choisie, ce qui entraîne plusieurs analyses de table. La forme de la requête est assez simple, ressemblant à ceci:
SELECT t1.id
FROM t1
INNER JOIN t2 ON t1.id = t2.t1_id
LEFT OUTER JOIN t3 ON t2.id = t3.t2_id
LEFT OUTER JOIN t4 ON t3.t4_id = t4.id
WHERE t4.id = some_GUID
En jouant avec la requête, j'ai remarqué que lorsque je lui suggère d'utiliser une jointure de fusion pour l'une des jointures, elle s'exécute plusieurs fois plus rapidement. Je peux comprendre ceci: la fusion de jointure est une meilleure option pour les données jointes, mais SQL Server ne l'estime pas correctement en choisissant les boucles imbriquées.
Ce que je ne comprends pas bien, c'est pourquoi cette indication de jointure modifie toutes les estimations pour tous les opérateurs de plan? En lisant différents articles et livres, j'ai supposé que les estimations de cardinalité étaient effectuées avant la construction du plan, donc l'utilisation d'un indice n'aurait pas changé les estimations, mais indiquerait explicitement à SQL Server d'utiliser une implémentation de jointure physique particulière.
Ce que je vois, cependant, c'est que l'indice de fusion fait que toutes les estimations deviennent à peu près parfaites. Pourquoi cela se produit-il et existe-t-il des techniques courantes pour que l'optimiseur de requêtes fasse une meilleure estimation sans indice - étant donné que les statistiques le permettent évidemment?
UPD: des plans d'exécution anonymisés peuvent être trouvés ici: https://www.dropbox.com/s/hchfuru35qqj89s/merge_join.sqlplan?dl=0 https://www.dropbox.com/s/38sjtv0t7vjjfdp/no_hints_join.sqlplan?dl = 0
J'ai vérifié les statistiques utilisées par les deux requêtes en utilisant TF 3604, 9292 et 9204, et celles-ci sont identiques. Cependant, les index analysés / recherchés diffèrent entre les requêtes.
En plus de cela, j'ai essayé d'exécuter la requête avec OPTION (FORCE ORDER)
- elle s'exécute encore plus rapidement que d'utiliser la jointure de fusion, en choisissant HASH MATCH pour chaque jointure.