2010-06-24 12 views
9

¿Cuál es la manera eficiente de verificar un nulo o valor para una columna en una consulta SQL? Considere una tabla sql table con la columna entera column que tiene un índice. @value puede ser un número entero o nulo, por ejemplo: 16 o nulo.Manera eficiente de comparar para un NULO o valor para una columna en SQL

Pregunta 1: No estoy seguro, pero parece que uno no debe confiar en el cortocircuito en SQL. Sin embargo, la consulta siguiente siempre funciona correctamente cuando @value es un número entero o nulo.

select * from 
table 
where (@value is null or column = @value) 

La siguiente consulta es una versión ampliada de la consulta anterior. Funciona correctamente también.

select * from 
table 
where ((@value is null) 
    or (@value is not null and column = @value)) 

¿Las 2 consultas anteriores tendrían la ventaja del índice?

Consulta 2: La consulta a continuación compara la columna con @value no nulo, sino que compara la columna column consigo misma, que siempre será verdadera y devuelve todo. Funciona correctamente también. ¿Aprovechará esta consulta el índice?

select * from 
table 
where (column = isnull(@value, column)) 

¿Cuál es la mejor manera?

Nota: Si la respuesta varía según las bases de datos, estoy interesado en MS-SQL.

+4

La mejor manera de determinar si algo va a utilizar un índice o no, es a cree una tabla de prueba con muchas filas, cree el índice y verifique el plan de consulta para su consulta. –

+1

Tenga en cuenta que Query 2 ** no ** devolverá valores de la tabla donde la columna es nula, ya que la condición null = null se evalúa como nula, no verdadera.Marca –

+0

, gracias por señalar eso. la columna no es nula, así que eso no sucedería en este caso. – hIpPy

Respuesta

1

Las variaciones en esta pregunta han aparecido varias veces en los últimos días (¿por qué estas cosas siempre ocurren en grupos?). La respuesta corta es que sí, SQL Server cortocircuitará la lógica SI crea el plan de consulta con valores conocidos. Entonces, si tiene ese código en una secuencia de comandos donde se establecen las variables, entonces creo que debe cortocircuitar la lógica (prueba para estar seguro). Sin embargo, si está en un procedimiento almacenado, SQL Server creará un plan de consulta con anticipación y no sabrá si puede o no hacer un cortocircuito en la consulta, ya que no conoce los valores de los parámetros en el momento de la generación. el plan de consulta.

Independientemente de si está cortocircuitado o no, SQL Server debería poder usar el índice si esa es la única parte de su consulta. Sin embargo, si la variable es NULL, probablemente no desee que SQL Server use el índice porque será inútil.

Si está en un procedimiento almacenado, la mejor opción es usar OPCIÓN (RECOMP) en su consulta. Esto hará que SQL Server cree un nuevo plan de consulta cada vez. Esto es un poco elevado, pero las ganancias generalmente superan por mucho. Esto SÓLO es bueno para SQL 2008 e incluso solo para algunos de los paquetes de servicios posteriores. Hubo un error con RECOMPILE antes de que lo dejara inútil. Para obtener más información, consulte great article de Erland Sommarskog sobre el tema. Específicamente, deseará buscar en las secciones de SQL estático.

1

Para aclarar un punto, SQL realmente no tiene un cortocircuito como lo conocemos en los lenguajes basados ​​en C. Lo que parece un cortocircuito es realmente que en la lógica ternaria de SQL Server O VERDADERO NULL evalúa como TRUE

TRUE OR NULL ===> TRUE 
TRUE AND NULL ===> NULL 

Ej:

if 1=null or 1=1 print 'true' else print 'false' 
if 1=null and 1=1 print 'true' else print 'false' 
Cuestiones relacionadas