Tengo curiosidad por saber cuál de las siguientes opciones sería más eficiente.
Siempre he sido un poco cauteloso al usarlo IN
porque creo que SQL Server convierte el conjunto de resultados en una gran IF
declaración. Para un conjunto de resultados grande, esto podría resultar en un rendimiento deficiente. Para conjuntos de resultados pequeños, no estoy seguro de que sea preferible ninguno. Para conjuntos de resultados grandes, ¿no EXISTS
sería más eficiente?
WHERE EXISTS (SELECT * FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)
vs.
WHERE bx.BoxID IN (SELECT BoxID FROM Base WHERE [Rank = 2])
sql-server
sql-server-2005
exists
query-performance
sql-in
Randy Minder
fuente
fuente
select 1 from Base...
en suwhere exists
puesto que en realidad no se preocupan por los resultados, sólo que en realidad existe una fila.Respuestas:
EXISTS
será más rápido porque una vez que el motor haya encontrado un golpe, dejará de mirar ya que la condición ha demostrado ser cierta.Con
IN
, recopilará todos los resultados de la subconsulta antes de continuar con el procesamiento.fuente
La respuesta aceptada es miope y la pregunta un poco suelta en eso:
Creo que el optimizador es lo suficientemente inteligente como para convertir entre "en" y "existe" cuando hay una diferencia de costo significativa debido a (1) y (2); de lo contrario, puede usarse solo como una sugerencia (por ejemplo, existe para alentar el uso de un índice de búsqueda en el lado derecho).
Ambos formularios se pueden convertir para unir formularios internamente, invertir el orden de combinación y ejecutar como bucle, hash o combinación, en función de los recuentos de filas estimados (izquierda y derecha) y la existencia del índice en los lados izquierdo, derecho o ambos.
fuente
IN
yEXISTS
. Intente idear cualquier caso en el que no obtengan el mismo plan (aunque esto no se aplica aNOT IN
yNOT EXISTS
)Hice algunas pruebas en SQL Server 2005 y 2008, y tanto en EXISTS como en IN regresaron con exactamente el mismo plan de ejecución real, como han dicho otros. El Optimizador es óptimo. :)
Sin embargo, algo a tener en cuenta, EXISTS, IN y JOIN a veces pueden devolver resultados diferentes si no formula su consulta correctamente: http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210 .aspx
fuente
Aquí hay muchas respuestas engañosas, incluida la muy votada (aunque no creo que sus operaciones hayan significado daño). La respuesta corta es: son iguales.
Hay muchas palabras clave en el lenguaje (T-) SQL, pero al final, lo único que realmente sucede en el hardware son las operaciones como se ve en el plan de consulta de ejecución.
La operación relacional (teoría matemática) que hacemos cuando invocamos
[NOT] IN
y[NOT] EXISTS
es la semi-unión (anti-unión cuando se usaNOT
). No es una coincidencia que las correspondientes operaciones del servidor SQL tengan el mismo nombre . No hay operación que mencioneIN
ni enEXISTS
ningún lugar - solo (anti) semiuniones. Por lo tanto, no hay forma de que una opciónIN
frente a una lógica equivalenteEXISTS
pueda afectar el rendimiento porque hay una y única forma, la operación de ejecución (anti) semiunión, de obtener sus resultados .Un ejemplo:
Consulta 1 ( plan )
Consulta 2 ( plan )
fuente
Iría con EXISTS sobre IN, vea el enlace a continuación:
SQL Server: JOIN vs IN vs EXISTS - la diferencia lógica
Crédito del blog: https://stackoverflow.com/users/31345/mladen-prajdic
fuente
Los planes de ejecución suelen ser idénticos en estos casos, pero hasta que no vea cómo el optimizador tiene en cuenta todos los demás aspectos de los índices, etc., nunca lo sabrá.
fuente
Entonces, IN no es lo mismo que EXISTS ni producirá el mismo plan de ejecución.
Por lo general, EXISTS se usa en una subconsulta correlacionada, lo que significa que UNIRÁ la consulta interna EXISTS con su consulta externa. Eso agregará más pasos para producir un resultado, ya que necesita resolver las uniones de consultas externas y las uniones de consultas internas luego coinciden con sus cláusulas where para unir ambas.
Por lo general, IN se usa sin correlacionar la consulta interna con la consulta externa, y eso se puede resolver en un solo paso (en el mejor de los casos).
Considera esto:
Si usa IN y el resultado de la consulta interna son millones de filas de valores distintos, probablemente funcionará MÁS LENTO que EXISTS dado que la consulta EXISTS funciona correctamente (tiene los índices correctos para unirse con la consulta externa).
Si usa EXISTS y la combinación con su consulta externa es compleja (lleva más tiempo realizarla, no hay índices adecuados), la consulta se ralentizará según el número de filas en la tabla externa; a veces, el tiempo estimado para completar puede ser en días. Si el número de filas es aceptable para su hardware dado, o la cardinalidad de los datos es correcta (por ejemplo, menos valores DISTINCT en un conjunto de datos grande), IN puede funcionar más rápido que EXISTS.
Todo lo anterior se notará cuando tenga una buena cantidad de filas en cada tabla (por justo me refiero a algo que excede el procesamiento de su CPU y / o los umbrales de RAM para el almacenamiento en caché).
Entonces la RESPUESTA es DEPENDE. Puede escribir una consulta compleja dentro de IN o EXISTS, pero como regla general, debe intentar usar IN con un conjunto limitado de valores distintos y EXISTS cuando tenga muchas filas con muchos valores distintos.
El truco consiste en limitar el número de filas a escanear.
Saludos,
MarianoC
fuente
Para optimizar el
EXISTS
, sea muy literal; algo tiene que estar ahí, pero en realidad no necesita ningún dato devuelto por la subconsulta correlacionada. Solo está evaluando una condición booleana.Entonces:
WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)
Debido a que la subconsulta correlacionada es
RBAR
, el primer resultado obtenido hace que la condición sea verdadera y no se procesa más.fuente
Fuera de mi cabeza y no se garantiza que sea correcto: creo que el segundo será más rápido en este caso.
IN
producirá un cortocircuito tan pronto como encuentre una coincidencia.fuente