LEFT JOIN
jest absolutnie nie szybszy niż INNER JOIN
. W rzeczywistości jest wolniejszy; z definicji sprzężenie zewnętrzne (LEFT JOIN
lub RIGHT JOIN
) musi wykonać całą pracę INNER JOIN
plus dodatkowa praca polegająca na rozszerzaniu wyników o wartości zerowej. Oczekuje się również, że zwróci więcej wierszy, co dodatkowo zwiększy całkowity czas wykonania po prostu ze względu na większy rozmiar zestawu wyników.
(I nawet jeśli LEFT JOIN
było szybciej w konkretnych sytuacji z powodu trudnej do wyobrażenia konfluencji czynników, nie jest funkcjonalnie równoważny z INNER JOIN
, więc nie możesz po prostu zastąpić wszystkich wystąpień jednego z drugim!)
Najprawdopodobniej Twoje problemy z wydajnością leżą gdzie indziej, na przykład nie mając odpowiednio zindeksowanego klucza kandydującego lub klucza obcego. 9 stołów to całkiem sporo, więc spowolnienie może być dosłownie wszędzie. Jeśli opublikujesz swój schemat, być może będziemy mogli podać więcej szczegółów.
Edytuj:
Zastanawiając się dalej nad tym, mogłem wymyślić jedną okoliczność, w której LEFT JOIN
może być szybszy niż INNER JOIN
, i to wtedy:
- Niektóre tabele są bardzo mały (powiedzmy, poniżej 10 rzędów);
- Tabele nie mają wystarczającej liczby indeksów, aby objąć zapytanie.
Rozważ ten przykład:
CREATE TABLE #Test1
(
ID int NOT NULL PRIMARY KEY,
Name varchar(50) NOT NULL
)
INSERT #Test1 (ID, Name) VALUES (1, 'One')
INSERT #Test1 (ID, Name) VALUES (2, 'Two')
INSERT #Test1 (ID, Name) VALUES (3, 'Three')
INSERT #Test1 (ID, Name) VALUES (4, 'Four')
INSERT #Test1 (ID, Name) VALUES (5, 'Five')
CREATE TABLE #Test2
(
ID int NOT NULL PRIMARY KEY,
Name varchar(50) NOT NULL
)
INSERT #Test2 (ID, Name) VALUES (1, 'One')
INSERT #Test2 (ID, Name) VALUES (2, 'Two')
INSERT #Test2 (ID, Name) VALUES (3, 'Three')
INSERT #Test2 (ID, Name) VALUES (4, 'Four')
INSERT #Test2 (ID, Name) VALUES (5, 'Five')
SELECT *
FROM #Test1 t1
INNER JOIN #Test2 t2
ON t2.Name = t1.Name
SELECT *
FROM #Test1 t1
LEFT JOIN #Test2 t2
ON t2.Name = t1.Name
DROP TABLE #Test1
DROP TABLE #Test2
Jeśli uruchomisz to i przejrzysz plan wykonania, zobaczysz, że INNER JOIN
zapytanie rzeczywiście kosztuje więcej niż LEFT JOIN
, ponieważ spełnia dwa powyższe kryteria. Dzieje się tak, ponieważ SQL Server chce wykonać dopasowanie skrótu dla INNER JOIN
, ale robi zagnieżdżone pętle dla LEFT JOIN
; pierwszy to normalnie znacznie szybciej, ale ponieważ liczba wierszy jest tak mała i nie ma indeksu do użycia, operacja haszowania okazuje się być najdroższą częścią zapytania.
Możesz zobaczyć ten sam efekt, pisząc program w swoim ulubionym języku programowania, aby wykonać dużą liczbę wyszukiwań na liście z 5 elementami, w porównaniu z tabelą mieszającą z 5 elementami. Ze względu na rozmiar wersja tablicy mieszającej jest w rzeczywistości wolniejsza. Ale zwiększ go do 50 elementów lub 5000 elementów, a wersja listy spowalnia się do indeksowania, ponieważ dla tablicy mieszającej jest O(N) kontra O(1).
Ale zmień to zapytanie na ID
kolumna zamiast Name
a zobaczysz zupełnie inną historię. W takim przypadku wykonuje zagnieżdżone pętle dla obu zapytań, ale INNER JOIN
wersja jest w stanie zastąpić jedno ze skanowanych indeksów klastrowych wyszukiwaniem - co oznacza, że będzie to dosłownie o rząd wielkości szybciej z dużą liczbą rzędów.
Tak więc wniosek jest mniej więcej taki, jak wspomniałem w kilku akapitach powyżej; jest to prawie na pewno problem z indeksowaniem lub pokryciem indeksu, prawdopodobnie w połączeniu z jedną lub kilkoma bardzo małymi tabelami. To jedyne okoliczności, w których SQL Server może czasami wybieraj gorszy plan wykonania dla INNER JOIN
niż LEFT JOIN
.