Eu tenho uma consulta em uma tabela grande que se parece com isso:
declare @myIdParam int = 1
select *
from myTable
where (@myIdParam is null or myTable.Id = @myIdParam)
Existem vários condicionais semelhantes como este na cláusula where e também há muitas junções, mas este é um resumo.
Efetivamente, se @myIdParam for nulo, não queremos restringir os resultados usando esse parâmetro.
Eu não sou um profissional de banco de dados, mas pelos meus testes parece que essa verificação NULL é feita para todos os registros e não é otimizada de forma alguma.
Se eu remover a verificação nula e supor que o parâmetro não é nulo, a consulta retornará instantaneamente. Caso contrário, leva até dez segundos.
Existe uma maneira de otimizar isso para que a verificação seja feita apenas uma vez em tempo de execução?
sql-server
null
Mystagogue
fonte
fonte
OPTION(RECOMPILE)
Respostas:
Uma maneira é usar o SQL dinâmico, usando uma verificação nula para adicionar opcionalmente essa parte da cláusula where.
fonte
sp_ExecuteSQL
está ausente e o@vc_dynamicsql
parâmetro precisa ser aNVARCHAR
.Sempre que você coloca uma função em torno de uma coluna `ISNULL (@var, table.col) ', por exemplo, você remove a capacidade do SQL de usar um índice. Essa é realmente a opção com melhor desempenho se você deseja mantê-la em uma única consulta.
Caso contrário, você tem duas opções. A primeira é a SQL dinâmica e a resposta do @ Mystagogue é suficiente para que, caso contrário, você possa fazer duas consultas como esta:
Nesse formato e no SQL dinâmico, você obterá um plano de consulta diferente para cada uma das consultas (o que potencialmente produzirá melhor desempenho).
fonte
Bem, você pode:
No entanto, lembre-se de que a
nullif()
função é essencialmente um invólucrocase
. Não é uma bala de prata que elimina magicamenteOR
e, portanto, acelera a consulta.fonte
UNION
s. Quando tive essa tarefa exata, escolhi o SQL dinâmico.