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
,d
esUNIQUE
yb
es relativamente pequeño en comparación cona
, luego la condición se propaga a la subconsulta y al simpleINNER JOIN
se utiliza (conb
principal) -
Si hay un índice en
b.d
yd
no esUNIQUE
, entonces la condición también se propaga yLEFT SEMI JOIN
se usa También se puede usar para la condición anterior. -
Si hay un índice en ambos
b.d
ya.c
y son grandes, entoncesMERGE SEMI JOIN
se usa -
Si no hay índice en ninguna tabla, se crea una tabla hash en
b
yHASH SEMI JOIN
se 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.