Tengo un SP con un parámetro que tiene NULL como valor predeterminado y luego quiero hacer una consulta como esta:
SELECT ...
FROM ...
WHERE a.Blah = @Blah AND (a.VersionId = @VersionId OR (@VersionId IS NULL AND a.VersionId IS NULL));
Lo WHERE
anterior verifica tanto un valor no NULL como un valor NULL para @VersionId
.
¿Sería mejor en términos de rendimiento utilizar una IF
instrucción y duplicar la consulta en una que busque NULL y otra NULL de esa manera? :
IF @VersionId IS NULL BEGIN
SELECT ...
FROM ...
WHERE a.Blah = @Blah AND a.VersionId IS NULL;
ELSE BEGIN
SELECT ...
FROM ...
WHERE a.Blah = @Blah AND a.VersionId = @VersionId;
END
¿O el optimizador de consultas lo hace esencialmente igual?
ACTUALIZAR:
(Nota: estoy usando SQL Server)
(Y hasta donde yo sé, el uso a.VersionId = @VersionId
para ambos casos no funcionará, ¿verdad?)
sql-server-2008
performance
usuario2173353
fuente
fuente
Respuestas:
Este patrón
puede ser reemplazado con
Esto le permitirá hacer coincidir un NULL con un NULL y permitirá que el motor use un índice de manera
column
eficiente. Para un excelente análisis en profundidad de esta técnica, lo remito al artículo del blog de Paul White:Como hay dos argumentos en su caso particular, puede usar la misma técnica de emparejamiento con
@Blah
, de esa manera podrá reescribir la cláusula WHERE completa de manera más o menos concisa:Esto funcionará rápido con un índice activado
(a.Blah, a.VersionId)
.En este caso, si. En todas las versiones (al menos) desde SQL Server 2005 en adelante, el optimizador puede reconocer el patrón
col = @var OR (@var IS NULL AND col IS NULL)
y reemplazarlo con laIS
comparación adecuada . Esto depende de la coincidencia interna de reescritura, por lo que puede haber casos más complejos en los que esto no siempre es confiable.En las versiones de SQL Server de 2008 SP1 CU5 inclusive , también tiene la opción de utilizar la optimización de incrustación de parámetros a través de
OPTION (RECOMPILE)
, donde el valor de tiempo de ejecución de cualquier parámetro o variable se incrusta en la consulta como un literal antes de la compilación.Entonces, al menos en gran medida, en este caso la elección es una cuestión de estilo, aunque la
INTERSECT
construcción es innegablemente compacta y elegante.Los siguientes ejemplos muestran el 'mismo' plan de ejecución para cada variación (literales versus referencias de variables excluidas):
fuente