Actualización:
Este artículo de mi blog resume tanto mi respuesta como mis comentarios a otras respuestas y muestra los planes de ejecución reales:
SELECT *
FROM a
WHERE a.c IN (SELECT d FROM b)
SELECT a.*
FROM a
JOIN b
ON a.c = b.d
Estas consultas no son equivalentes. Pueden arrojar resultados diferentes si su tabla b no se conserva la clave (es decir, los valores de b.d no son únicos).
El equivalente de la primera consulta es el siguiente:
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT d
FROM b
) bo
ON a.c = bo.d
Si b.d es UNIQUE y marcado como tal (con un UNIQUE INDEX o UNIQUE CONSTRAINT ), entonces estas consultas son idénticas y lo más probable es que usen planes idénticos, ya que SQL Server es lo suficientemente inteligente como para tener esto en cuenta.
SQL Server puede emplear uno de los siguientes métodos para ejecutar esta consulta:
-
Si hay un índice en
a.c,desUNIQUEybes relativamente pequeño en comparación cona, luego la condición se propaga a la subconsulta y al simpleINNER JOINse utiliza (conbprincipal) -
Si hay un índice en
b.dydno esUNIQUE, entonces la condición también se propaga yLEFT SEMI JOINse usa También se puede usar para la condición anterior. -
Si hay un índice en ambos
b.dya.cy son grandes, entoncesMERGE SEMI JOINse usa -
Si no hay índice en ninguna tabla, se crea una tabla hash en
byHASH SEMI JOINse utiliza.
Ninguno de estos métodos vuelve a evaluar toda la subconsulta cada vez.
Consulte esta entrada en mi blog para obtener más detalles sobre cómo funciona:
Hay enlaces para todos los RDBMS es de los cuatro grandes.