2010-06-25 18 views
17

he notado una serie de consultas en el trabajo y en el SO se utilizan limitaciones en la forma:isnull vs es nulo

isnull(name,'') <> '' 

¿Hay alguna razón en particular por la gente hace eso y no el más terso

name is not null 

¿Es un legado o un problema de rendimiento?

+0

Martin Smith tiene razón si está citando el código con precisión. Si en realidad es algo así como isnull (name, '') <> @name, entonces evitará que SQL use ningún índice, pero obtendrá un resultado más parecido al que describe Donnie – Matt

+0

@Matt: Sí, cometí un error en el código que di en el ejemplo. Ahora está arreglado. – tgandrews

Respuesta

30
where isnull(name,'') <> '' 

es equivalente a

where name is not null and name <> '' 

que a su vez es equivalente a

where name <> '' 

(si el nombre IS NULL que expresión final evaluaría a lo desconocido y no se devuelve la fila)

El uso del patrón ISNULL dará como resultado un escaneo y es menos effi ciente como se puede ver en la prueba siguiente.

SELECT ca.[name], 
     [number], 
     [type], 
     [low], 
     [high], 
     [status] 
INTO TestTable 
FROM [master].[dbo].[spt_values] 
     CROSS APPLY (SELECT [name] 
        UNION ALL 
        SELECT '' 
        UNION ALL 
        SELECT NULL) ca 


CREATE NONCLUSTERED INDEX IX_TestTable ON dbo.TestTable(name) 

GO 


SELECT name FROM TestTable WHERE isnull(name,'') <> '' 

SELECT name FROM TestTable WHERE name is not null and name <> '' 
/*Can be simplified to just WHERE name <> '' */ 

Que debería darle el plan de ejecución que necesita.

enter image description here

+0

"El uso de este patrón ... es menos eficiente ..." El patrón es el uso de ISNULL o IS IS NULL ... OR = constructo? –

+1

@KarlKieninger - El patrón es el uso de 'ISNULL' - originalmente había algunas imágenes del plan de ejecución que lo aclaraban. Los regenerará ... –

2

isnull(name,'') <> :name es la abreviatura de (name is null or name <> :name) (suponiendo que :name nunca contiene la cadena vacía, por lo que los shorthands como este pueden ser malos).

En cuanto a rendimiento, depende. or declaraciones en where cláusulas pueden dar muy mal rendimiento. Sin embargo, las funciones en columnas perjudican el uso del índice. Como de costumbre: perfil.

+0

'(el nombre es nulo o '' <>: nombre)' .... ¿no? –

1
isnull(name,'') <> name 

Bueno, puedo verlos usando esto porque de esta manera si el nombre no coincide o si es nulo, se devuelve como una comparación fallida. Esto realmente significa: name is null o name <> name

Donde como este name is not null simplemente comprueba si el nombre es nulo.

12
is not null 

Solo comprobará si el campo no es nulo. Si el campo contiene una cadena vacía, entonces el campo ya no es nulo.

isnull(name, '') <> name 

Comprueba si hay una cadena vacía y una cadena vacía.

1

no significan lo mismo.

name is not null 

Esto comprueba los registros donde el campo nombre es nula

isnull(name,'') <> name 

Ésta cambia el valor de los campos nulos en la cadena vacía para que puedan ser utilizados en una comparación. En SQL Server (pero no en Oracle, creo), si un valor es nulo y se usa para comparar equidad o desigualdad, no se considerará porque nulo significa que no conozco el valor y, por lo tanto, no es un valor real.Por lo tanto, si desea asegurarse de que se tengan en cuenta los registros nulos al hacer la comparación, necesita ISNULL o COALESCE (que es el término ASCII STANDARD para usar como ISNULL no funciona en todas las bases de datos).

Lo que debe buscar en la differnece es entre

isnull(a.name,'') <> b.name 

a.name <> b.name

continuación, se entiende por qué se necesita la ISNULL para obtener resultados correctos.

1

Aparentemente leí mal su pregunta. Así que permítanme golpeo mi primera respuesta y tratar éste:

isnull(name,'') <> '' 

es un atajo equivocado para

name is not null and name <> '' 
0

Además, si desea hacer uso del índice en esa columna, utilice

name is not null and name <> '' 
1

Otros han señalado la diferencia funcional. En cuanto al problema de rendimiento, en Postgres he encontrado que, oh, debo mencionar que Postgres tiene una función "coalesce" que es el equivalente del "isnull" que se encuentra en algunos otros dialectos SQL, pero en Postgres, que dice

where coalesce(foobar,'')='' 

es significativamente más rápido que

where foobar is null or foobar='' 

Además, puede ser asombrosamente mucho más rápido que decir

where foobar>'' 

sobre

where foobar!='' 

Una mayor que la prueba puede usar el índice y omitir todos los espacios en blanco, mientras que una prueba no igual tiene que hacer una lectura de archivo completo. (Suponiendo que tiene un índice en el campo y no se utiliza ningún otro índice de preferencia)

0

Estas dos consultas no son las mismas. Por ejemplo, no tengo un segundo nombre, este es un hecho conocido, que puede ser almacenado como

MiddleName='' 

Sin embargo, si no sabemos el segundo nombre de alguien, podemos almacenar NULL. Entonces, ISNULL (MiddleName, '') significa "personas sin nombres intermedios conocidos".

0

Es para manejar tanto la cadena vacía como NULL. Si bien es bueno poder hacer con una afirmación, isnull es sintaxis patentada. Escribiría esto usando Portable Standard SQL como

NULLIF(name, '') IS NOT NULL