Tenho um SP com um parâmetro que tem NULL como valor padrão e então quero fazer uma consulta assim:
SELECT ...
FROM ...
WHERE a.Blah = @Blah AND (a.VersionId = @VersionId OR (@VersionId IS NULL AND a.VersionId IS NULL));
O WHERE
acima verifica um valor não NULL e um valor NULL para @VersionId
.
Seria melhor em termos de desempenho usar uma IF
instrução e duplicar a consulta em uma que procura não NULL e outra para NULL assim? :
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
Ou o otimizador de consulta torna essencialmente o mesmo?
ATUALIZAR:
(Nota: estou usando o SQL Server)
(E até onde eu sei, usar a.VersionId = @VersionId
para ambos os casos não vai funcionar, vai?)
Esse padrão
pode ser substituído por
Isso permitirá que você corresponda a um NULL com um NULL e permitirá que o mecanismo use um índice com
column
eficiência. Para uma excelente análise aprofundada dessa técnica, indico o artigo do blog de Paul White:Como existem dois argumentos em seu caso particular, você pode usar a mesma técnica de correspondência com
@Blah
– dessa forma, você poderá reescrever toda a cláusula WHERE de forma mais ou menos concisa:Isso funcionará rapidamente com um índice em
(a.Blah, a.VersionId)
.Neste caso, sim. Em todas as versões (pelo menos) do SQL Server 2005 em diante, o otimizador pode reconhecer o padrão e substituí-lo pela comparação
col = @var OR (@var IS NULL AND col IS NULL)
adequada .IS
Isso depende da correspondência de reescrita interna, portanto, pode haver casos mais complexos em que isso nem sempre é confiável.Nas versões do SQL Server a partir de 2008 SP1 CU5 inclusive , você também tem a opção de usar a Otimização de Incorporação de Parâmetros via
OPTION (RECOMPILE)
, onde o valor de tempo de execução de qualquer parâmetro ou variável é inserido na consulta como um literal antes da compilação.Assim, pelo menos em grande parte, neste caso a escolha é uma questão de estilo, embora a
INTERSECT
construção seja inegavelmente compacta e elegante.Os exemplos a seguir mostram o 'mesmo' plano de execução para cada variação (literais versus referências de variáveis excluídas):