J'ai entendu des informations mitigées à ce sujet et j'espère un avis canonique ou expert.
Si j'ai plusieurs LEFT OUTER JOIN
s, chacun dépendant du dernier, est-il préférable de les imbriquer?
Pour un exemple artificiel, le JOIN
to MyParent
dépend du JOIN
to MyChild
:
http://sqlfiddle.com/#!3/31022/5
SELECT
{columns}
FROM
MyGrandChild AS gc
LEFT OUTER JOIN
MyChild AS c
ON c.[Id] = gc.[ParentId]
LEFT OUTER JOIN
MyParent AS p
ON p.[id] = c.[ParentId]
Comparé à http://sqlfiddle.com/#!3/31022/7
SELECT
{columns}
FROM
MyGrandChild AS gc
LEFT OUTER JOIN
(
MyChild AS c
LEFT OUTER JOIN
MyParent AS p
ON p.[id] = c.[ParentId]
)
ON c.[Id] = gc.[ParentId]
Comme indiqué ci-dessus, ils produisent différents plans de requête dans SS2k8
sql-server-2008-r2
performance
join
Matthieu
la source
la source
JOIN
est unINNER JOIN
ON ... ON
deux fois de suite (entre parenthèses ou non) est très déroutant.use plan
astuce fonctionne lors de la transplantation du deuxième plan de requête dans le premier, mais pas l'inverse.Réponses:
Ce n'est absolument pas une réponse canonique mais j'ai remarqué que pour les plans de requête de boucles imbriquées montrés dans le SQL Fiddle, il était possible d'appliquer le plan de la requête 2 à la requête 1 avec l'utilisation de l'
USE PLAN
indice, mais la tentative d'opération inverse échoue avecLa désactivation de la règle de transformation de l'optimiseur
ReorderLOJN
empêche également l'indicateur de plan précédemment réussi de réussir.Expérimenter avec de plus grandes quantités de données montre que SQL Server est certainement capable de transformer
(A LOJ B) LOJ C
àA LOJ (B LOJ C)
naturellement aussi bien mais je ne vois aucune preuve que l'inverse est vrai.Un cas très artificiel où la première requête fonctionne mieux que la seconde est
Ce qui donne des plans
Pour moi, la requête 1 avait un temps écoulé de 108 ms contre 1163 ms pour la requête 2.
Requête 1
Requête 2
On peut donc supposer provisoirement que la première syntaxe ("non imbriquée") est potentiellement bénéfique car elle permet de considérer plus d'ordres de jointure potentiels, mais je n'ai pas fait de tests suffisamment exhaustifs pour avoir une grande confiance en cela en règle générale.
Il peut être tout à fait possible de trouver des contre-exemples où Query 2 fonctionne mieux. Essayez les deux et regardez les plans d'exécution.
la source
il n'y a pas de type JOIN appelé "Jointure imbriquée". il s'agit d'une autre variante de l'écriture que JOIN peut être à des fins de lisibilité. vous pouvez les voir comme des "sous-requêtes" à des fins de compréhension uniquement.
si vous êtes plus préoccupé par la lisibilité du code, alors mon avis est que c'est le choix de l'individu avec lequel il peut se conférer.
Et si vous êtes préoccupé par les performances de la requête et que l'indication "Force JOIN ORDER" n'est pas utilisée dans la requête, alors peu importe si la requête est écrite avec "Nested Join" ou All "Outer Join". Le serveur SQL propose la commande en fonction du coût de la jonction de deux tables et / ou du résultat. SQL Server effectue le JOIN entre deux ensembles de données à la fois uniquement.
en fait, imaginez que dans la deuxième façon "jointure imbriquée" si le serveur SQL décide de faire la deuxième partie, "MyChild AS c LEFT OUTER JOIN MyParent AS p ON p. [id] = c. [ParentId]" et ces tables se produisent pour avoir des lignes qui vont être supprimées dans NEXT LEFT JOIN. dans ce cas, le serveur SQL a dépensé des ressources inutiles pour effectuer l'OUTER JOIN ces deux et transmettre ce résultat au JOIN suivant.
vous pouvez également consulter une question similaire posée et répondue de manière appropriée ici. Comprendre la syntaxe de «jointure imbriquée»
la source
FORCE JOIN ORDER
indice?