sql >> Base de Datos >  >> RDS >> Sqlserver

IN vs. JOIN con conjuntos de filas grandes

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 es UNIQUE y b es relativamente pequeño en comparación con a , luego la condición se propaga a la subconsulta y al simple INNER JOIN se utiliza (con b principal)

  • Si hay un índice en b.d y d no es UNIQUE , entonces la condición también se propaga y LEFT SEMI JOIN se usa También se puede usar para la condición anterior.

  • Si hay un índice en ambos b.d y a.c y son grandes, entonces MERGE SEMI JOIN se usa

  • Si no hay índice en ninguna tabla, se crea una tabla hash en b y HASH 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.