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ärUNIQUEochbär relativt liten jämfört meda, sedan sprids villkoret till underfrågan och den vanligaINNER JOINanvänds (medbledande) -
Om det finns ett index på
b.dochdä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.docha.coch de är stora, sedanMERGE SEMI JOINanvänds -
Om det inte finns något index på någon tabell byggs en hashtabell på
bochHASH SEMI JOINanvä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.