Sans tenir compte des performances, les résultats des requêtes A et B ci-dessous donneront-ils le même résultat? Que diriez-vous de C et D?
-- A
select *
from a left join b
on <blahblah>
left join c
on <blahblan>
-- B
select *
from a left join c
on <blahblah>
left join b
on <blahblan>
-- C
select *
from a join b
on <blahblah>
join c
on <blahblan>
-- D
select *
from a join c
on <blahblah>
join b
on <blahblan>
Pour INNER
rejoint, non, l'ordre n'a pas d'importance. Les requêtes renverront les mêmes résultats, tant que vous modifiez vos sélections de SELECT *
à SELECT a.*, b.*, c.*
.
Pour (LEFT
, RIGHT
ou FULL
) OUTER
joint, oui, l'ordre est important - et ( mis à jour ) les choses sont beaucoup plus compliquées.
Premièrement, les jointures externes ne sont pas commutatives, donc a LEFT JOIN b
n'est pas identique à b LEFT JOIN a
.
Les jointures externes ne sont pas non plus associatives, donc dans vos exemples qui impliquent les deux propriétés (commutativité et associativité):
a LEFT JOIN b
ON b.ab_id = a.ab_id
LEFT JOIN c
ON c.ac_id = a.ac_id
équivaut à:
a LEFT JOIN c
ON c.ac_id = a.ac_id
LEFT JOIN b
ON b.ab_id = a.ab_id
mais:
a LEFT JOIN b
ON b.ab_id = a.ab_id
LEFT JOIN c
ON c.ac_id = a.ac_id
AND c.bc_id = b.bc_id
n'est pas équivalent à:
a LEFT JOIN c
ON c.ac_id = a.ac_id
LEFT JOIN b
ON b.ab_id = a.ab_id
AND b.bc_id = c.bc_id
Un autre exemple d'associativité (heureusement plus simple). Pensez à ceci comme (a LEFT JOIN b) LEFT JOIN c
:
a LEFT JOIN b
ON b.ab_id = a.ab_id -- AB condition
LEFT JOIN c
ON c.bc_id = b.bc_id -- BC condition
Ceci est équivalent à a LEFT JOIN (b LEFT JOIN c)
:
a LEFT JOIN
b LEFT JOIN c
ON c.bc_id = b.bc_id -- BC condition
ON b.ab_id = a.ab_id -- AB condition
seulement parce que nous avons "Nice" ON
conditions. ON b.ab_id = a.ab_id
et c.bc_id = b.bc_id
sont des contrôles d'égalité et n'impliquent pas de comparaisons NULL
.
Vous pouvez même avoir des conditions avec d'autres opérateurs ou avec des opérateurs plus complexes comme: ON a.x <= b.x
ou ON a.x = 7
ou ON a.x LIKE b.x
ou ON (a.x, a.y) = (b.x, b.y)
et les deux requêtes seraient toujours équivalentes.
Si, toutefois, l'un de ceux-ci impliquait IS NULL
ou une fonction liée à des valeurs nulles telle que COALESCE()
, par exemple, si la condition était b.ab_id IS NULL
, les deux requêtes ne seraient pas équivalentes.
pour les jointures régulières, ce n'est pas le cas. TableA join TableB
produira le même plan d'exécution que TableB join TableA
(vos exemples C et D seront donc les mêmes)
pour la gauche et la droite rejoint il fait. TableA left Join TableB
est différent de TableB left Join TableA
, MAIS c'est la même chose que TableB right Join TableA
Si vous essayez de rejoindre C sur un champ de B avant de rejoindre B, c’est-à-dire:
SELECT A.x, A.y, A.z FROM A
INNER JOIN C
on B.x = C.x
INNER JOIN b
on A.x = B.x
votre requête échouera, donc dans ce cas, l'ordre est important.
optimiseur Oracle choisit l'ordre de jointure des tables pour la jointure interne. L'optimiseur choisit l'ordre de jointure des tables uniquement dans les clauses FROM simples. Vous pouvez consulter la documentation Oracle sur leur site Web. Et pour la jointure extérieure gauche, la réponse la plus votée est la bonne. L'optimiseur choisit l'ordre de jointure optimal ainsi que l'index optimal pour chaque table. L'ordre de jointure peut affecter le meilleur choix d'index. L'optimiseur peut choisir un index comme chemin d'accès pour une table s'il s'agit de la table interne, mais pas s'il s'agit de la table externe (et s'il n'y a pas d'autres qualifications).
L'optimiseur choisit l'ordre de jointure des tables uniquement dans les clauses FROM simples. La plupart des jointures utilisant le mot-clé JOIN sont transformées en jointures simples. L'optimiseur choisit donc leur ordre de jointure.
L'optimiseur ne choisit pas l'ordre de jointure pour les jointures externes; il utilise l'ordre spécifié dans l'instruction.
Lors de la sélection d'un ordre de jointure, l'optimiseur prend en compte: La taille de chaque table Les index disponibles sur chaque table Indique si un index d'une table est utile dans un ordre de jointure particulier Le nombre de lignes et de pages à analyser pour chaque table de chaque table. rejoindre l'ordre