2010-01-14 18 views
93

Tengo curiosidad por saber cuál de las siguientes opciones sería más eficiente?
Siempre he sido un poco cauteloso sobre el uso de IN porque creo que SQL Server convierte el conjunto de resultados en una gran declaración IF. Para un gran conjunto de resultados, esto podría dar como resultado un bajo rendimiento. Para pequeños conjuntos de resultados, no estoy seguro de que sea preferible. Para grandes conjuntos de resultados, ¿no sería más eficiente el EXISTS?SQL Server IN vs. EXISTS Rendimiento

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]) 
+6

La mejor manera de averiguarlo es probarlo y hacer algunas mediciones. –

+10

hay ** got ** para ser un montón de duplicados para esto ...... –

+0

@marc_s: sí, pero creo que realmente depende de cada caso. Supongo que la respuesta canónica es klausbyskov (o quien quiera reclamar el estado de la técnica). – RedFilter

Respuesta

117

EXISTS será más rápido porque una vez que el motor ha encontrado un éxito, será dejar de mirar como la condición ha demostrado cierto.
Con IN recogerá todos los resultados de la sub-consulta antes del procesamiento posterior.

+3

Ese es un buen punto. La instrucción IN requiere que SQL Server genere un conjunto de resultados completo, y luego creo una gran declaración IF, creo. –

+63

Esto solía ser cierto, pero en las versiones actuales (al menos 2008) el optimizador es mucho más inteligente ... realmente trata IN() como EXISTS(). –

+10

@ Aaron - Sí, normalmente el optimizador producirá internamente un mejor plan. Sin embargo, depender de los atajos internos podría ser perjudicial en escenarios más complejos. –

-1

De la parte superior de mi cabeza y no garantiza que sea correcta: Creo que el segundo será más rápida en este caso.

  1. En el primero, la subconsulta correlacionada probablemente hará que se ejecute la subconsulta para cada fila.
  2. En el segundo ejemplo, la subconsulta solo debería ejecutarse una vez, ya que no está correlacionada.
  3. En el segundo ejemplo, IN se cortocircuitará tan pronto como encuentre una coincidencia.
3

Los planes de ejecución suelen ser idénticos en estos casos, pero hasta que vea cómo el optimizador toma en cuenta todos los demás aspectos de índices, etc., nunca lo sabrá.

33

He hecho algunas pruebas en SQL Server 2005 y 2008, y tanto en EXISTS como en IN vuelven con el mismo plan de ejecución real, como han dicho otros. El Optimizador es óptimo. :)

Algo a tener en cuenta, sin embargo, existe, EN, y unirse a veces puede devolver resultados diferentes si no lo hace plantear la consulta a la perfección: http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210.aspx

1

para optimizar el EXISTS, ser muy literales; algo solo tiene que estar allí, pero en realidad no necesita ningún dato devuelto por la subconsulta correlacionada. Estás evaluando una condición booleana.

Así:

WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)

Debido a que el sub-consulta correlacionada es RBAR, el primer resultado golpe hace que la condición de verdad, y se procesa sin más.

+0

Siempre sería extremadamente cauteloso al usar la codificación LEFT JOIN + NULL, porque es muy fácil perder los resultados si no es muy cuidadoso en su manejo NULL. Raramente encontré una situación en la que EXISTS o un CTE (para encontrar duplicación o inserción sintética para datos faltantes) no cumplen con los mismos requisitos y superan a IZQUIERDA + NULA –

+2

TOP 1 debe ser completa (o evento redundante) cuando se usa con EXISTS. EXISTS siempre regresa tan pronto como encuentre una fila coincidente. –

+0

No he visto ningún beneficio de rendimiento con este enfoque hasta ahora. Por favor, muestre algunas capturas de pantalla de los Planes de ejecución – montewhizdoh

28

la respuesta aceptada es miope y la cuestión un poco floja en que:

1) Ni menciona explícitamente si un índice de cobertura está presente en la izquierda, derecha, o en ambos lados.

2) Ninguno de los dos tiene en cuenta el tamaño de la entrada del lado izquierdo y el entrada del lado derecho.
(La pregunta solo menciona un conjunto grande resultado conjunto).

Creo que el optimizador es lo suficientemente inteligente como para convertir entre "en" vs "existe" cuando hay una diferencia significativa de costes debido a (1) y (2), de lo contrario, sólo puede ser utilizado como una pista (por ejemplo, existe para fomentar el uso de un índice buscable en el lado derecho).

Ambos formularios se pueden convertir para unir formularios internamente, tienen el orden de combinación invertido y se ejecutan como bucle, hash o fusión, según el recuento de filas estimado (izquierda y derecha) y existencia de índice en izquierda, derecha o ambos lados.

+2

no sé por qué esta excelente respuesta no ha recibido más atención. Comprender el índice/estructura para ambas partes podría tener un impacto, estoy de acuerdo. Bien dicho. – SheldonH