Eu tenho um SP com um parâmetro que tem NULL como valor padrão e, em seguida, quero fazer uma consulta como esta:
SELECT ...
FROM ...
WHERE a.Blah = @Blah AND (a.VersionId = @VersionId OR (@VersionId IS NULL AND a.VersionId IS NULL));
O WHERE
acima verifica tanto um valor não NULL como um valor NULL @VersionId
.
Em termos de desempenho, seria melhor usar uma IF
instrução e duplicar a consulta em uma que procure por NULL e outra por NULL dessa maneira? :
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, tanto quanto eu sei, usar a.VersionId = @VersionId
para ambos os casos não funcionará, funcionará?)
sql-server-2008
performance
user2173353
fonte
fonte
Respostas:
Esse padrão
pode ser substituído por
Isso permitirá que você combine um NULL com um NULL e permitirá que o mecanismo use um índice com
column
eficiência. Para uma excelente análise detalhada dessa técnica, refiro-lhe o artigo do blog de Paul White:Como existem dois argumentos no seu caso em particular, você pode usar a mesma técnica de correspondência com
@Blah
- dessa forma, você poderá reescrever a cláusula WHERE inteira de forma mais ou menos concisa:Isso funcionará rapidamente com um índice ativado
(a.Blah, a.VersionId)
.Nesse caso sim. Em todas as versões (pelo menos) do SQL Server 2005 em diante, o otimizador pode reconhecer o padrão
col = @var OR (@var IS NULL AND col IS NULL)
e substituí-lo pelaIS
comparação adequada . 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 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)
, na qual o valor de tempo de execução de qualquer parâmetro ou variável é incorporado na consulta como um literal antes da compilação.Portanto, pelo menos em grande parte, nesse 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 (excluídas as referências literais versus as variáveis):
fonte