Niezależnie od wydajności, czy otrzymam ten sam wynik z poniższych zapytań A i B? A co z C i 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
Tylko uczeń
źródło
źródło
<blahblah>
? czy dołączasz do A do B i od A do C, czy dołączasz do A do B i B do C?Odpowiedzi:
W przypadku
INNER
dołączeń nie, kolejność nie ma znaczenia. Zapytania zwrócą te same wyniki, o ile zmienisz wybrane opcje zSELECT *
naSELECT a.*, b.*, c.*
.Dla (
LEFT
,RIGHT
lubFULL
)OUTER
sprzężeń, tak, sprawy zamówienie - i ( zaktualizowane ) rzeczy są o wiele bardziej skomplikowane.Po pierwsze, połączenia zewnętrzne nie są przemienne, więc
a LEFT JOIN b
nie są takie same jakb LEFT JOIN a
Sprzężenia zewnętrzne również nie są asocjacyjne, więc w twoich przykładach, które dotyczą obu właściwości (przemienności i asocjatywności):
odpowiada :
ale:
nie jest równoważne z :
Kolejny (miejmy nadzieję prostszy) przykład asocjatywności. Pomyśl o tym jako
(a LEFT JOIN b) LEFT JOIN c
:Jest to równoważne z
a LEFT JOIN (b LEFT JOIN c)
:tylko dlatego, że mamy „miłe”
ON
warunki. ZarównoON b.ab_id = a.ab_id
ic.bc_id = b.bc_id
są kontrole równości i nie wiążą sięNULL
porównań.Można nawet mieć warunki z innymi operatorami lub bardziej skomplikowanych, takich jak:
ON a.x <= b.x
lubON a.x = 7
lubON a.x LIKE b.x
lubON (a.x, a.y) = (b.x, b.y)
i dwa zapytania nadal byłyby równoważne.Jeśli jednak którykolwiek z nich dotyczy
IS NULL
lub funkcja jest powiązana z zeramiCOALESCE()
, na przykład jeśli warunek był spełnionyb.ab_id IS NULL
, wówczas dwa zapytania nie byłyby równoważne.źródło
a.somecol > 0 OR b.someothercol > 0
; skojarzenie może się nie powieść dla tego stanu.INNER JOIN
i następująceLEFT JOIN
. Czy to działa tak, że najpierw kwerenda będzie naFilter
podstawie rekordów,INNER JOIN
a następnie zastosuje sięLEFT JOIN
do nichFiltered
?ON
klauzuli (tj. „Specyfikacji łączenia”) do nowej lokalizacji . Jest to jednak tylko składnia. Jeśli użyjesz notacji algebry relacyjnej (gdzie specyfikacja łączenia jest umieszczona poniżej operatora łączenia), wówczas skojarzenie staje się bardziej widoczne. Twój argument pokazuje tylko, że sprzężenia zewnętrzne nie są przemienne , co jest poprawnedla zwykłych dołączeń tak nie jest.
TableA join TableB
stworzy taki sam plan wykonania jakTableB join TableA
(więc twoje przykłady C i D byłyby takie same)dla lewych i prawych połączeń to robi.
TableA left Join TableB
jest inny niżTableB left Join TableA
, ale jest taki sam jakTableB right Join TableA
źródło
Jeśli spróbujesz dołączyć do C na polu z B przed dołączeniem do B, tj .:
Twoje zapytanie nie powiedzie się, więc w tym przypadku kolejność ma znaczenie.
źródło
Optymalizator Oracle wybiera kolejność łączenia tabel dla łączenia wewnętrznego. Optymalizator wybiera kolejność łączenia tabel tylko w prostych klauzulach FROM. U może sprawdzić dokumentację wyroczni na swojej stronie internetowej. A dla lewych, prawych stron zewnętrznych najbardziej głosowana odpowiedź jest odpowiednia. Optymalizator wybiera optymalną kolejność łączenia, a także optymalny indeks dla każdej tabeli. Kolejność łączenia może mieć wpływ na to, który indeks jest najlepszym wyborem. Optymalizator może wybrać indeks jako ścieżkę dostępu do tabeli, jeśli jest to tabela wewnętrzna, ale nie, jeśli jest to tabela zewnętrzna (i nie ma dalszych kwalifikacji).
Optymalizator wybiera kolejność łączenia tabel tylko w prostych klauzulach FROM. Większość złączeń za pomocą słowa kluczowego JOIN jest spłaszczonych do prostych złączeń, więc optymalizator wybiera kolejność łączenia.
Optymalizator nie wybiera kolejności łączenia dla połączeń zewnętrznych; używa kolejności określonej w instrukcji.
Przy wyborze kolejności łączenia optymalizator bierze pod uwagę: Rozmiar każdej tabeli Indeksy dostępne w każdej tabeli Czy indeks w tabeli jest przydatny w określonej kolejności łączenia Liczba wierszy i stron do skanowania dla każdej tabeli w każdej dołączyć do zamówienia
źródło