¿Diferencia de rendimiento para COALESCE versus ISNULL?

48

He visto a mucha gente usar la función COALESCE en lugar de ISNULL. De las búsquedas en Internet, descubrí que COALESCE es el estándar ANSI, por lo que hay una ventaja de que sabemos qué esperar al usarlo. Sin embargo, ISNULL parece más fácil de leer ya que parece más claro lo que está haciendo.

También me doy cuenta de que ISNULL es un poco complicado ya que actúa de manera diferente en diferentes servidores de bases de datos y en diferentes idiomas.

Todo eso, en mi opinión, se reduce a estilo y estándares. Dado que el estilo es subjetivo, ¿hay alguna razón para usar COALESCE sobre ISNULL (o viceversa)? Específicamente, ¿hay una ventaja de rendimiento de uno sobre el otro?

Ricardo
fuente
1
No veo mencionado en ninguna de las respuestas que una subconsulta en una COALESCE se evalúe dos veces.
Martin Smith
44
"ISNULL parece más fácil de leer ya que parece más claro lo que está haciendo" - ¿en serio? Encuentro que el nombre no es intuitivo: esperaría que devuelva un booleano que indica si una expresión se resolvió como nula o desconocida. El nombre no COALESCEes intuitivo;)
cuando el

Respuestas:

40
  • ISNULL es específico de Sybase / SQL Server
  • COALESCE es portátil

Entonces

  • ISNULL toma 2 argumentos
  • COALESCE toma argumentos 1-n

Finalmente, y la parte divertida. El resultado tipo de datos y longitud / precisión / escala

Este último bit es por qué ISNULL se usa generalmente porque es más predecible (?) Y COALESCE puede agregar conversiones de tipo de datos no intencionadas: de ahí proviene el bit "es más lento"

DECLARE @len10 varchar(10); --leave it NULL
SELECT
    ISNULL(@len10, '0123456789ABCDEF'),     -- gives 0123456789
    COALESCE(@len10, '0123456789ABCDEF');   -- gives 0123456789ABCDEF

Todos los tipos de datos son iguales, no verá ninguna diferencia práctica ...

gbn
fuente
22

Como Mark señaló, será difícil encontrar diferencias de rendimiento; Creo que otros factores serán más importantes. Para mí, siempre uso COALESCE, y la mayoría de esto ya ha sido mencionado por usted o Mark:

  • COALESCE es el estándar ANSI. Es una cosa menos de la que me tengo que preocupar si voy a portar mi código. Para mí, personalmente, esto no es tan importante, porque sé cuán infrecuentemente tales puertos ocurren realmente fuera del mundo del aula de Celko, pero para algunas personas esto es un beneficio.
  • Al contrario de lo que dijo sobre la legibilidad, creo que puede ser más difícil leer ISNULL, especialmente para los usuarios que vienen de otros idiomas o plataformas donde ISNULL devuelve un valor booleano (que no existe en SQL Server). Por supuesto, COALESCE es más difícil de deletrear, pero al menos no conduce a suposiciones incorrectas.
  • COALESCE es mucho más flexible, como puedo decir COALESCE (a, b, c, d) mientras que con ISNULL tendría que anidar mucho para lograr lo mismo.

También debe asegurarse de saber cómo se maneja la precedencia de tipo de datos utilizando las dos funciones si lo está utilizando con diferentes tipos de datos / precisiones, etc.

Nota

Hay una excepción Estos se manejan de manera diferente en las versiones actuales de SQL Server:

SELECT COALESCE((SELECT some_aggregate_query),0); 

SELECT ISNULL((SELECT some_aggregate_query),0); 

La COALESCEvariante se ejecutará some_aggregate_querydos veces (una para verificar el valor y otra para devolverlo cuando no sea cero), mientras ISNULLque solo ejecutará la subconsulta una vez. Hablo de algunas otras diferencias aquí:

Aaron Bertrand
fuente