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,djestUNIQUEibjest stosunkowo mały w porównaniu doa, warunek jest propagowany do podzapytania i zwykłegoINNER JOINjest używany (zbwiodący) -
Jeśli istnieje indeks na
b.didnie jestUNIQUE, warunek jest również propagowany iLEFT SEMI JOINjest używany. Może być również użyty do powyższego warunku. -
Jeśli istnieje indeks na obu
b.dia.ci są duże, toMERGE SEMI JOINjest używany -
Jeśli nie ma indeksu w żadnej tabeli, tablica mieszająca jest budowana na
biHASH SEMI JOINjest 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.