Tengo una consulta en una tabla grande que se ve así:
declare @myIdParam int = 1
select *
from myTable
where (@myIdParam is null or myTable.Id = @myIdParam)
Hay varios condicionales similares como este en la cláusula where, y también hay muchas uniones, pero este es un resumen.
Efectivamente, si @myIdParam es nulo, no queremos restringir los resultados usando este parámetro.
No soy un DB pro, pero de mis pruebas parece que esta verificación NULL se realiza para cada registro y no se optimiza de ninguna manera.
Si elimino la comprobación nula y asumo que el parámetro no es nulo, la consulta vuelve instantáneamente. De lo contrario, demora hasta diez segundos.
¿Hay alguna manera de optimizar esto para que la verificación se realice solo una vez en tiempo de ejecución?
sql-server
null
Mystagogue
fuente
fuente
OPTION(RECOMPILE)
Respuestas:
Una forma es usar SQL dinámico, usando una verificación nula para agregar opcionalmente esa parte de la cláusula where.
fuente
sp_ExecuteSQL
y el@vc_dynamicsql
parámetro debe ser aNVARCHAR
.Cada vez que coloca una función alrededor de una columna `ISNULL (@var, table.col) ', por ejemplo, elimina la capacidad de SQL para usar un índice. Esta es realmente la mejor opción si desea mantenerla en una sola consulta.
De lo contrario, tienes dos opciones. El primero es SQL dinámico y la respuesta de @ Mystagogue es suficiente para eso, de lo contrario, puede realizar dos consultas como esta:
Tanto en este formato como en el SQL dinámico, obtendrá un plan de consulta diferente para cada una de las consultas (lo que potencialmente generará un mejor rendimiento).
fuente
Bien tu puedes:
Tenga en cuenta, sin embargo, que la
nullif()
función es esencialmente una envolturacase
. No es una bala de plata que elimina mágicamenteOR
y, por lo tanto, acelera la consulta.fuente
UNION
electrónicos. Cuando tuve esta tarea exacta, elegí SQL dinámico.