Mise à jour :
Cet article de mon blog résume à la fois ma réponse et mes commentaires sur d'autres réponses, et montre les plans d'exécution réels :
SELECT *
FROM a
WHERE a.c IN (SELECT d FROM b)
SELECT a.*
FROM a
JOIN b
ON a.c = b.d
Ces requêtes ne sont pas équivalentes. Ils peuvent donner des résultats différents si votre table b n'est pas la clé conservée (c'est-à-dire les valeurs de b.d ne sont pas uniques).
L'équivalent de la première requête est le suivant :
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT d
FROM b
) bo
ON a.c = bo.d
Si b.d est UNIQUE et marqué comme tel (avec un UNIQUE INDEX ou UNIQUE CONSTRAINT ), alors ces requêtes sont identiques et utiliseront très probablement des plans identiques, puisque SQL Server est assez intelligent pour en tenir compte.
SQL Server peut utiliser l'une des méthodes suivantes pour exécuter cette requête :
-
S'il y a un index sur
a.c,destUNIQUEetbest relativement petit par rapport àa, la condition est propagée dans la sous-requête et le simpleINNER JOINest utilisé (avecbmenant) -
S'il y a un index sur
b.detdn'est pasUNIQUE, alors la condition est également propagée etLEFT SEMI JOINest utilisé. Il peut également être utilisé pour la condition ci-dessus. -
S'il y a un index sur les deux
b.deta.cet ils sont grands, alorsMERGE SEMI JOINest utilisé -
S'il n'y a pas d'index sur une table, alors une table de hachage est construite sur
betHASH SEMI JOINest utilisé.
Aucun de ces méthodes réévalue l'ensemble de la sous-requête à chaque fois.
Voir cette entrée dans mon blog pour plus de détails sur la façon dont cela fonctionne :
Il existe des liens pour tous les RDBMS 's des quatre grands.