Sans tenir compte des performances, vais-je obtenir le même résultat des requêtes A et B ci-dessous? 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>
sql
join
relational-database
Juste un apprenant
la source
la source
<blahblah>
? vous joignez A à B et A à C, ou vous joignez A à B et B à C?Réponses:
Pour les
INNER
jointures, non, l'ordre n'a pas d'importance. Les requêtes renverront les mêmes résultats, tant que vous modifiez vos sélections deSELECT *
àSELECT a.*, b.*, c.*
.Pour (
LEFT
,RIGHT
ouFULL
) lesOUTER
jointures, oui, les questions d'ordre - et ( mises à jour ) les choses sont beaucoup plus compliquées.Premièrement, les jointures externes ne sont pas commutatives, ce
a LEFT JOIN b
n'est donc pas la même chose queb LEFT JOIN a
Les jointures externes ne sont pas associatives non plus, donc dans vos exemples qui impliquent à la fois les propriétés (commutativité et associativité):
équivaut à :
mais:
n'est pas équivalent à :
Un autre exemple d'associativité (espérons-le plus simple). Considérez cela comme
(a LEFT JOIN b) LEFT JOIN c
:Cela équivaut à
a LEFT JOIN (b LEFT JOIN c)
:seulement parce que nous avons des
ON
conditions «agréables» . Les deuxON b.ab_id = a.ab_id
etc.bc_id = b.bc_id
sont des contrôles d'égalité et n'impliquent pas deNULL
comparaisons.Vous pouvez même avoir des conditions avec d'autres opérateurs ou des plus complexes comme:
ON a.x <= b.x
ouON a.x = 7
ouON a.x LIKE b.x
ouON (a.x, a.y) = (b.x, b.y)
et les deux requêtes seraient toujours équivalentes.Cependant, si l'un de ces éléments était impliqué
IS NULL
ou une fonction liée à des valeurs nulles commeCOALESCE()
, par exemple, si la condition l'étaitb.ab_id IS NULL
, les deux requêtes ne seraient pas équivalentes.la source
a.somecol > 0 OR b.someothercol > 0
; l'associativité pourrait échouer pour cette condition.INNER JOIN
et un suivantLEFT JOIN
. Est-ce que cela fonctionne comme ça d'abord la requête seraFilter
les enregistrements sur la base deINNER JOIN
, puis s'appliqueraLEFT JOIN
auxFiltered
enregistrements?ON
clause (c'est-à-dire la "spécification de jointure") vers un nouvel emplacement . Ce n'est cependant que de la syntaxe. Si vous utilisez la notation d'algèbre relationnelle (où la spécification de jointure est placée sous l'opérateur de jointure), l'associativité devient plus évidente. Votre argument montre seulement que les jointures externes ne sont pas commutatives , ce qui est correctpour les jointures régulières, ce n'est pas le cas.
TableA join TableB
produira le même plan d'exécution queTableB join TableA
(donc vos exemples C et D seraient les mêmes)pour les jointures gauche et droite, c'est le cas.
TableA left Join TableB
est différent deTableB left Join TableA
, MAIS c'est le même queTableB right Join TableA
la source
Si vous essayez de joindre C sur un champ de B avant de rejoindre B, c'est-à-dire:
votre requête échouera, donc dans ce cas l'ordre est important.
la source
L'optimiseur Oracle choisit l'ordre de jointure des tables pour la jointure interne. L'optimiseur choisit l'ordre de jointure des tables uniquement dans des clauses FROM simples. Vous pouvez consulter la documentation d'Oracle sur leur site Web. Et pour la jointure externe gauche, droite, 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 quel index est le meilleur choix. 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 il n'y a pas d'autres qualifications).
L'optimiseur choisit l'ordre de jointure des tables uniquement dans des clauses FROM simples. La plupart des jointures utilisant le mot clé JOIN sont aplaties en jointures simples, de sorte que l'optimiseur choisit 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 Si un index sur une table est utile dans un ordre de jointure particulier Le nombre de lignes et de pages à analyser pour chaque table dans chaque ordre de jonction
la source