SQL JOIN vs IN rendimiento?

164

Tengo un caso en el que usar un JOIN o un IN me dará los resultados correctos ... ¿Qué suele tener un mejor rendimiento y por qué? ¿Cuánto depende de qué servidor de base de datos esté ejecutando? (FYI estoy usando MSSQL)

Polaris878
fuente
:) En realidad estaba buscando un artículo diferente que usé cuando investigué en algo parecido un tiempo atrás, y topé con uno que, por error
AdaTheDev
Perdón por el posible engaño ... no encontré esa pregunta cuando estaba buscando
Polaris878

Respuestas:

196

En términos generales, INy JOINson consultas diferentes que pueden producir resultados diferentes.

SELECT  a.*
FROM    a
JOIN    b
ON      a.col = b.col

no es lo mismo que

SELECT  a.*
FROM    a
WHERE   col IN
        (
        SELECT  col
        FROM    b
        )

, a menos que b.colsea ​​único.

Sin embargo, este es el sinónimo de la primera consulta:

SELECT  a.*
FROM    a
JOIN    (
        SELECT  DISTINCT col
        FROM    b
        )
ON      b.col = a.col

Si la columna de unión está UNIQUEmarcada como tal, ambas consultas producen el mismo plan SQL Server.

Si no es así, entonces INes más rápido que JOINencendido DISTINCT.

Consulte este artículo en mi blog para obtener detalles sobre el rendimiento:

Quassnoi
fuente
Sí que tiene sentido que ejecutarían lo mismo si la columna de unión es única (que es en mi caso)
Polaris878
1
En una nota similar, ¿debo usar IN (SELECT DISTINCT ...) o simplemente IN (SELECT ...)?
muué
8
@ orlandu63: INimplica DISTINCT. SQL Serveres lo suficientemente inteligente como para notarlo y generará los mismos planes para ambas consultas. Sin embargo, no estoy seguro de cómo RDBMSse comportarán los demás .
Quassnoi
>> IN y JOIN son consultas diferentes que pueden arrojar resultados diferentes. ¿Puede explicar por qué generaría un resultado diferente en este caso incluso si b.col no es único?
Abhijeet
explainextended.com/2009/06/16/in-vs-join-vs-exists Realmente me ayuda ... Gracias ...
Abbas Galiyakotwala
6

Eso es bastante difícil de decir: para saber cuál funciona mejor, necesitaría realmente perfilar los tiempos de ejecución.

Como regla general, creo que si tiene índices en sus columnas de clave externa, y si está usando solo (o principalmente) condiciones de UNIÓN INTERNA, entonces la UNIÓN será un poco más rápida.

Pero tan pronto como comience a usar OUTER JOIN, o si carece de índices de clave externa, el IN podría ser más rápido.

Bagazo

marc_s
fuente
Yo también estaba pensando en esto ... porque parece que JOIN es un caso más común y probablemente estaría optimizado ''
Polaris878,
4

Una crítica interesante sobre las diferencias lógicas: SQL Server: JOIN vs IN vs EXISTS - la diferencia lógica

Estoy bastante seguro de que, suponiendo que se mantengan las relaciones y los índices, un Join funcionará mejor en general (se requiere más esfuerzo para trabajar con esa operación que con otras). Si lo piensa conceptualmente, entonces es la diferencia entre 2 consultas y 1 consulta.

Debe conectarlo al analizador de consultas e intentarlo y ver la diferencia. También mire el Plan de ejecución de consultas e intente minimizar los pasos.

AdamSane
fuente
4

Este hilo es bastante antiguo, pero aún se menciona a menudo. Para mi gusto personal, es un poco incompleto, porque hay otra forma de preguntar a la base de datos con la palabra clave EXISTS, que encontré que es más rápida la mayoría de las veces.

Entonces, si solo está interesado en los valores de la tabla a, puede usar esta consulta:

SELECT  a.*
FROM    a
WHERE   EXISTS (
    SELECT  *
    FROM    b
    WHERE   b.col = a.col
    )

La diferencia podría ser enorme si col no está indexada, porque db no tiene que encontrar todos los registros en b que tengan el mismo valor en col, solo tiene que encontrar el primero. Si no hay un índice en b.col y muchos registros en el escaneo de la tabla ba podrían ser la consecuencia. Con IN o un JOIN esto sería una exploración de tabla completa, con EXISTS sería una exploración de tabla parcial (hasta que se encuentre el primer registro coincidente).

Si hay muchos registros en b que tienen el mismo valor de col, también desperdiciará mucha memoria para leer todos estos registros en un espacio temporal solo para descubrir que su condición está satisfecha. Con existe esto generalmente se puede evitar.

A menudo he encontrado EXISTE más rápido que IN, incluso si hay un índice. Depende del sistema de base de datos (el optimizador), los datos y, por último, el tipo de índice que se utiliza.

S.Roeper
fuente
3
En MSSql, el hecho de que existe es mejor que un IN parece no ser cierto. Para obtener más información: explainextended.com/2009/06/16/in-vs-join-vs-exists Aquí puede leer que: "Muchos piensan que EXISTS es más eficiente que IN, porque EXISTS devuelve solo una fila. Esto es no es cierto para SQL Server. Como podemos ver en los ejemplos anteriores, EXISTS e IN producen exactamente los mismos planes. Esto se debe a que EXISTS es más flexible que IN. Un IN siempre puede reescribirse como EXISTS (usando una condición WHERE simple con un equijoin ) pero no al revés ".
Micaël Félix
3

La implementación de cada base de datos, pero probablemente pueda adivinar que todas resuelven problemas comunes de la misma manera. Si está utilizando MSSQL, eche un vistazo al plan de ejecución que se genera. Puede hacerlo activando el generador de perfiles y los planes de ejecución. Esto le dará una versión de texto cuando ejecute el comando.

No estoy seguro de qué versión de MSSQL está utilizando, pero puede obtener una gráfica en SQL Server 2000 en el analizador de consultas. Estoy seguro de que esta funcionalidad está al acecho en algún lugar de SQL Server Studio Manager en versiones posteriores.

Echa un vistazo al plan de ejecución. En la medida de lo posible, evite los escaneos de tablas a menos que, por supuesto, su tabla sea pequeña, en cuyo caso un escaneo de tablas es más rápido que usar un índice. Lea sobre las diferentes operaciones de unión que produce cada escenario diferente.

uridio
fuente
1

El optimizador debe ser lo suficientemente inteligente como para darle el mismo resultado de cualquier manera para consultas normales. Verifique el plan de ejecución y deberían darle lo mismo. Si no lo hacen, normalmente consideraría que JOIN es más rápido. Sin embargo, todos los sistemas son diferentes, por lo que debe perfilar el código en su sistema para asegurarse.

Joel Coehoorn
fuente
55
¿Debería hacer? Tal vez. ¿Lo hace? No. Mira mi publicación.
cletus