Opdatering:
Denne artikel i min blog opsummerer både mit svar og mine kommentarer til et andet svar og viser faktiske udførelsesplaner:
SELECT *
FROM a
WHERE a.c IN (SELECT d FROM b)
SELECT a.*
FROM a
JOIN b
ON a.c = b.d
Disse forespørgsler er ikke ækvivalente. De kan give forskellige resultater, hvis din tabel b er ikke nøglebevaret (dvs. værdierne for b.d er ikke unikke).
Svaret til den første forespørgsel er følgende:
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT d
FROM b
) bo
ON a.c = bo.d
Hvis b.d er UNIQUE og markeret som sådan (med et UNIQUE INDEX eller UNIQUE CONSTRAINT ), så er disse forespørgsler identiske og vil sandsynligvis bruge identiske planer, da SQL Server er smart nok til at tage højde for dette.
SQL Server kan bruge en af følgende metoder til at køre denne forespørgsel:
-
Hvis der er et indeks på
a.c,derUNIQUEogber relativt lille sammenlignet meda, så spredes betingelsen ind i underforespørgslen og den almindeligeINNER JOINbruges (medbførende) -
Hvis der er et indeks på
b.dogder ikkeUNIQUE, så udbredes betingelsen også ogLEFT SEMI JOINanvendes. Den kan også bruges til ovenstående tilstand. -
Hvis der er et indeks på begge
b.doga.cog de er store, såMERGE SEMI JOINbruges -
Hvis der ikke er noget indeks på nogen tabel, er en hash-tabel bygget på
bogHASH SEMI JOINbruges.
Ingen af delene af disse metoder revurderer hele underforespørgslen hver gang.
Se dette indlæg i min blog for flere detaljer om, hvordan dette fungerer:
Der er links til alle RDBMS er af de fire store.