2010-02-18 73 views
21

Entiendo la diferencia entre estas funciones, pero mi pregunta es que al buscar un solo valor nulo, ¿ISNULL sería más rápido que usar COALESCE?¿Cuál es más rápido COALESCE O ISNULL?

por ejemplo

COALESCE(SELECT TOP 1 SomeValue FROM SomeTable, 0) 

vs

ISNULL(SELECT TOP 1 SomeValue FROM SomeTable, 0) 

Respuesta

3

ISNULL será más rápido, creo que debido a que tiene menor implementación de la función/código por sí mismo lo que es más rápido que COALESCE

1

Por favor, compruebe el enlace para preferir ISNULL sobre COALESCE cuando se le da la opción es que ISNULL tiende para producir planes de consulta que sean más eficientes que COALESCE.

  1. ISNULL Vs COALESCE

  2. ISNULL vs COALESCE speed test

  3. Por favor, compruebe el rendimiento: ISNULL vs. COALESCE

+0

El primer enlace dice que prefiere ISNULL, y el segundo enlace sugiere que COALESCE debería ser el preferido. – AdaTheDev

+0

por favor revise el enlace Rendimiento: ISNULL vs. COALESCE http://sqlblog.com/blogs/adam_machanic/archive/2006/07/12/performance-isnull-vs-coalesce.aspx – amexn

11

Echa un vistazo rápido a esto, ya que es interesante ver una serie de comparaciones diferentes sobre el rendimiento entre los 2. Creo que la publicación del blog this de Adam Machanic es más precisa en la evaluación comparativa de rendimiento realizada en este tema, donde conclusión es:

... y ISNULL parece bastante consistente superar el rendimiento de COALESCE por un promedio de 10 o 12 por ciento

Sin embargo, comparto la misma vista que lo que entonces continúa diciendo que la diferencia es bastante insignificante, por ejemplo en sus pruebas, un millón de ejecuciones aparecieron en promedio una diferencia de 0.7 s. ¿Vale la pena? Sugeriría que probablemente haya áreas más grandes para optimizar. Pero lea el artículo, es una buena lectura.

+2

Mi voto va para "¿Es esto? ¿Vale la pena? Sugeriría que probablemente hay áreas más grandes para optimizar ", dijo realmente. –

+0

"Pero esa es la diferencia entre 6 segundos y 5,3 segundos" - Para ser honesto, lo llamaría bastante significativo, al menos en su ejemplo trivial. – AaronHolland

6

En este caso, ISNULL es la mejor opción. Porque SQL Server interpreta la función COALESCE como una instrucción CASE.Por lo tanto, la consulta

COALESCE (SELECT TOP 1 SomeValue DE alguna_tabla, 0)

serán escritos por SQL Server como

  1. CASO
  2. CUANDO (SELECT TOP 1 SomeValue DE alguna_tabla) NO ES NULO
  3. ENTONCES (SELECCIONAR ARRIBA 1 SomeValue FROM SomeTable)
  4. ELSE 0
  5. FIN

Si se observa la interpretación anterior, "alguna_tabla" serán analizadas dos veces. Pero ISNULL se evaluará solo una vez.

+0

Existe un [Problema de Microsoft Connect] abierto (https://connect.microsoft.com/SQLServer/feedback/details/336002/unnecessarily-bad-performance-for-coalesce-subquery) con respecto al operador COALESCE que evalúa la misma consulta dos veces . – Aaroninus

-2

Acabo de ejecutar una prueba por mi cuenta db. Alrededor de 700k filas.

SELECT COUNT(*) FROM table WHERE COALESCE(field_1,field_2,field_3,field_4) IS NOT NULL 

Resultado de 12106 obtuvo en 56 segundos.

SELECT COUNT(*) FROM table WHERE field_1 IS NOT NULL OR field_2 IS NOT NULL OR field_3 IS NOT NULL OR field_4 IS NOT NULL 

Resultado de 12106 obtenido en 0.00 segundos.

+2

que no prueba la función isnull() – user314321

+0

@Fraser hmmm, verdadero. Podría volver a hacer la prueba con 'WHERE! ISNULL (field_1) ...'. ¿Pero no podemos estar seguros de que una llamada a la función 'ISNULL()' será aún más lenta que con 'IS NOT NULL'? –

0

Por lo que vale Tienes un caso de uso muy específico, así que utilicé una muestra de tu pregunta real sobre el primero en valor en una tabla que se me ocurrió y controlé la secuencia de comandos para otras variables. Supuse que algúnval era un int como lo usaste 0. Mi sugerencia es que elijas tu caso específico someval/sometable y hagas el test tú mismo.

declare @val int = 0; 
declare @time1 Datetime2 = getdate(); 
declare @time2 Datetime2 = getdate(); 
Select @time1 = GETDATE(); 
while @MyCounter < 1000000 
Begin 
Select @val = ISNULL((SELECT TOP 1 LocationID FROM location), 0) 
Select @MyCounter +=1; 
END 
Select @time2 = GETDATE(); 
Print datediff(millisecond,@time1,@time2); 
Select @MyCounter = 0; 
Select @time1 = GETDATE(); 
while @MyCounter < 1000000 
Begin 
Select @val = COALESCE((SELECT TOP 1 LocationID FROM Location), 0) 
Select @MyCounter +=1; 
END 
Select @time2 = GETDATE(); 
Print datediff(millisecond,@time1,@time2); 

Los resultados fueron bastante espectaculares, 11270 para isnull y 18930 para fusionarse. Invertir el orden de los bucles como segunda prueba produjo 18260 para unir y 10810 para isnull. Para su caso específico , diría que isnull es claramente más rápido.

Esto no quiere decir que sea mejor en cualquier otra situación. Usar valores ascendentes, o nvarchars o bits en lugar de int, o una columna que no sea una clave principal, o Anidar isnull versus agregar parámetros para unirlos podría cambiar las cosas.

Esto solo responde a la pregunta tal como se solicitó.

Cuestiones relacionadas