Do que não se trata:
Esta não é uma pergunta sobre consultas abrangentes que aceitam entrada do usuário ou usam variáveis.
Isso é estritamente sobre consultas onde ISNULL()
é usado na WHERE
cláusula para substituir NULL
valores por um valor canário para comparação com um predicado e diferentes maneiras de reescrever essas consultas para serem SARGable no SQL Server.
Por que você não se senta ali?
Nossa consulta de exemplo é em uma cópia local do banco de dados Stack Overflow no SQL Server 2016 e procura usuários com NULL
idade ou idade < 18.
SELECT COUNT(*)
FROM dbo.Users AS u
WHERE ISNULL(u.Age, 17) < 18;
O plano de consulta mostra um Scan de um índice não clusterizado bastante cuidadoso.
O operador de varredura mostra (graças às adições ao XML do plano de execução real nas versões mais recentes do SQL Server) que lemos cada linha ruim.
No geral, fazemos 9157 leituras e usamos cerca de meio segundo de tempo de CPU:
Table 'Users'. Scan count 1, logical reads 9157, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 485 ms, elapsed time = 483 ms.
A pergunta: Quais são as maneiras de reescrever essa consulta para torná-la mais eficiente e talvez até SARGable?
Fique à vontade para dar outras sugestões. Eu não acho que minha resposta seja necessariamente a resposta, e existem pessoas inteligentes o suficiente por aí para apresentar alternativas que podem ser melhores.
Se você quiser jogar no seu próprio computador, acesse aqui para baixar o banco de dados SO .
Obrigado!