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
,d
erUNIQUE
ogb
er relativt lille sammenlignet meda
, så spredes betingelsen ind i underforespørgslen og den almindeligeINNER JOIN
bruges (medb
førende) -
Hvis der er et indeks på
b.d
ogd
er ikkeUNIQUE
, så udbredes betingelsen også ogLEFT SEMI JOIN
anvendes. Den kan også bruges til ovenstående tilstand. -
Hvis der er et indeks på begge
b.d
oga.c
og de er store, såMERGE SEMI JOIN
bruges -
Hvis der ikke er noget indeks på nogen tabel, er en hash-tabel bygget på
b
ogHASH SEMI JOIN
bruges.
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.