Słyszałem mieszane informacje na ten temat i mam nadzieję na opinię kanoniczną lub ekspercką.
Jeśli mam wiele LEFT OUTER JOIN
s, każdy zależny od ostatniego, czy lepiej je zagnieżdżać?
Zobaczyć na dobry przykład, JOIN
aby MyParent
zależy od JOIN
celu 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]
W porównaniu do 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]
Jak pokazano powyżej, tworzą one różne plany zapytań w SS2k8
sql-server-2008-r2
performance
join
Mateusz
źródło
źródło
JOIN
jestINNER JOIN
ON ... ON
dwa razy z rzędu (nawias lub nie) jest bardzo mylące.use plan
Wskazówka działa po przesadzeniu drugiego planu zapytanie do pierwszej, ale nie odwrotnie.Odpowiedzi:
To absolutnie nie jest odpowiedź kanoniczna, ale zauważyłem, że dla planów zapytania zagnieżdżonych pętli pokazanych w skrzynce SQL możliwe było zastosowanie planu z Zapytania 2 do Zapytania 1 za pomocą
USE PLAN
podpowiedzi, ale próba odwrotnej operacji nie powiodła się zWyłączenie reguły transformacji optymalizatora
ReorderLOJN
uniemożliwia także odniesienie do wcześniejszego pomyślnego planu.Eksperymentowanie z większą ilością danych pokazuje, że SQL Server z pewnością jest w stanie przekształcić
(A LOJ B) LOJ C
się również wA LOJ (B LOJ C)
naturalny sposób, ale nie widziałem żadnych dowodów na to, że sytuacja jest odwrotna.Bardzo wymyślny przypadek, w którym pierwsze zapytanie działa lepiej niż drugie
Co daje plany
Dla mnie zapytanie 1 miało czas 108 ms w porównaniu do 1163 ms dla zapytania 2.
Zapytanie 1
Zapytanie 2
Można więc wstępnie założyć, że pierwsza („nieoparta”) składnia jest potencjalnie korzystna, ponieważ pozwala na rozważenie większej liczby potencjalnych zleceń łączenia, ale nie przeprowadziłem wystarczająco wyczerpujących testów, aby mieć co do tego zaufanie.
Może być całkiem możliwe wymyślenie przykładów, w których Zapytanie 2 działa lepiej. Spróbuj obu i spójrz na plany wykonania.
źródło
nie ma takiego typu JOIN o nazwie „Nested Join”. jest to kolejna odmiana pisania JOIN dla wygody czytelności. możesz je postrzegać jako „zapytania podrzędne” wyłącznie w celu zrozumienia celu.
jeśli bardziej martwisz się o czytelność kodu, to uważam, że to indywidualny wybór, z czym można się nadawać.
A jeśli martwisz się wydajnością zapytania i w zapytaniu nie jest używana wskazówka „Force JOIN ORDER”, to nie ma znaczenia, czy zapytanie jest napisane za pomocą „Nested Join” czy All „Outer Join”. Serwer SQL wymyśla zamówienie na podstawie kosztu połączenia dwóch tabel i / lub wyniku. SQL Server wykonuje JOIN tylko między dwoma zestawami danych naraz.
w rzeczywistości wyobraź sobie, że w drugi sposób „zagnieżdżone łączenie”, jeśli SQL Server zdecyduje się wykonać drugą część, „MyChild AS c POŁĄCZENIE ZEWNĘTRZNE MyParent AS p ON p. [id] = c. [ParentId]” i tabela się stanie mieć wiersze, które zostaną odrzucone w NASTĘPNYM LEWYM ŁĄCZU. w takim przypadku serwer SQL wydał niepotrzebne zasoby na wykonanie POŁĄCZENIA ZEWNĘTRZNEGO tych dwóch i przekazanie tego wyniku do następnego POŁĄCZENIA.
możesz również wyglądać na podobne pytanie zadane i odpowiednio udzielone odpowiedzi tutaj. Zrozumienie składni „Nested join”
źródło
FORCE JOIN ORDER
podpowiedzi?