Aktualizacja:
Ten artykuł na moim blogu podsumowuje zarówno moją odpowiedź, jak i komentarze do innych odpowiedzi, a także pokazuje rzeczywiste plany wykonania:
SELECT *
FROM a
WHERE a.c IN (SELECT d FROM b)
SELECT a.*
FROM a
JOIN b
ON a.c = b.d
Te zapytania nie są równoważne. Mogą dawać różne wyniki, jeśli Twoja tabela b
nie jest zachowywany klucz (tzn. wartości b.d
nie są unikalne).
Odpowiednikiem pierwszego zapytania jest:
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT d
FROM b
) bo
ON a.c = bo.d
Jeśli b.d
jest UNIQUE
i oznaczony jako taki (z UNIQUE INDEX
lub UNIQUE CONSTRAINT
), to te zapytania są identyczne i najprawdopodobniej będą korzystać z identycznych planów, ponieważ SQL Server
jest wystarczająco sprytny, aby wziąć to pod uwagę.
SQL Server
może użyć jednej z następujących metod do uruchomienia tego zapytania:
-
Jeśli istnieje indeks na
a.c
,d
jestUNIQUE
ib
jest stosunkowo mały w porównaniu doa
, warunek jest propagowany do podzapytania i zwykłegoINNER JOIN
jest używany (zb
wiodący) -
Jeśli istnieje indeks na
b.d
id
nie jestUNIQUE
, warunek jest również propagowany iLEFT SEMI JOIN
jest używany. Może być również użyty do powyższego warunku. -
Jeśli istnieje indeks na obu
b.d
ia.c
i są duże, toMERGE SEMI JOIN
jest używany -
Jeśli nie ma indeksu w żadnej tabeli, tablica mieszająca jest budowana na
b
iHASH SEMI JOIN
jest używany.
Ani z tych metod za każdym razem ponownie ocenia całe podzapytanie.
Zobacz ten wpis na moim blogu, aby uzyskać więcej informacji na temat tego, jak to działa:
Istnieją linki do wszystkich RDBMS
z wielkiej czwórki.