Uppdatering:
Den här artikeln i min blogg sammanfattar både mitt svar och mina kommentarer till andra svar, och visar faktiska genomförandeplaner:
SELECT *
FROM a
WHERE a.c IN (SELECT d FROM b)
SELECT a.*
FROM a
JOIN b
ON a.c = b.d
Dessa frågor är inte likvärdiga. De kan ge olika resultat om din tabell b
är inte nyckelbevarad (dvs. värdena för b.d
är inte unika).
Motsvarigheten till den första frågan är följande:
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT d
FROM b
) bo
ON a.c = bo.d
Om b.d
är UNIQUE
och markerad som sådan (med ett UNIQUE INDEX
eller UNIQUE CONSTRAINT
), då är dessa frågor identiska och kommer troligen att använda identiska planer, eftersom SQL Server
är smart nog att ta hänsyn till detta.
SQL Server
kan använda en av följande metoder för att köra den här frågan:
-
Om det finns ett index på
a.c
,d
ärUNIQUE
ochb
är relativt liten jämfört meda
, sedan sprids villkoret till underfrågan och den vanligaINNER JOIN
används (medb
ledande) -
Om det finns ett index på
b.d
ochd
är inteUNIQUE
, då sprids även villkoret ochLEFT SEMI JOIN
är använd. Den kan också användas för tillståndet ovan. -
Om det finns ett index på båda
b.d
ocha.c
och de är stora, sedanMERGE SEMI JOIN
används -
Om det inte finns något index på någon tabell byggs en hashtabell på
b
ochHASH SEMI JOIN
används.
Intedera av dessa metoder omvärderar hela underfrågan varje gång.
Se det här inlägget i min blogg för mer information om hur detta fungerar:
Det finns länkar för alla RDBMS
är av de fyra stora.