Aggiornamento:
Questo articolo nel mio blog riassume sia la mia risposta che i miei commenti ad altre risposte e mostra i piani di esecuzione effettivi:
SELECT *
FROM a
WHERE a.c IN (SELECT d FROM b)
SELECT a.*
FROM a
JOIN b
ON a.c = b.d
Queste query non sono equivalenti. Possono produrre risultati diversi se la tua tabella b non è conservata la chiave (cioè i valori di b.d non sono univoci).
L'equivalente della prima query è il seguente:
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT d
FROM b
) bo
ON a.c = bo.d
Se b.d è UNIQUE e contrassegnato come tale (con un UNIQUE INDEX o UNIQUE CONSTRAINT ), quindi queste query sono identiche e molto probabilmente utilizzeranno piani identici, poiché SQL Server è abbastanza intelligente da tenerne conto.
SQL Server può utilizzare uno dei seguenti metodi per eseguire questa query:
-
Se è presente un indice su
a.c,dèUNIQUEebè relativamente piccolo rispetto aa, quindi la condizione viene propagata nella sottoquery e nel sempliceINNER JOINviene utilizzato (conbprincipale) -
Se è presente un indice su
b.dednon èUNIQUE, quindi viene propagata anche la condizione eLEFT SEMI JOINviene usato. Può essere utilizzato anche per la condizione di cui sopra. -
Se è presente un indice su entrambi
b.dea.ce sono grandi, quindiMERGE SEMI JOINviene utilizzato -
Se non è presente alcun indice su nessuna tabella, viene creata una tabella hash su
beHASH SEMI JOINviene utilizzato.
Nemmeno di questi metodi rivaluta ogni volta l'intera sottoquery.
Vedi questa voce nel mio blog per maggiori dettagli su come funziona:
Ci sono collegamenti per tutti i RDBMS è dei quattro grandi.