Funções do SQL Server que são consideradas constantes de tempo de execução são avaliados apenas uma vez.
GETDATE()
é tal função, e DATEADD(..., constant, GETDATE())
também é uma constante de tempo de execução. Ao deixar a chamada de função real dentro da consulta, você permite que o otimizador veja qual valor será realmente usado (em oposição a uma detecção de valor variável) e, em seguida, ele pode ajustar suas estimativas de cardinalidade de acordo, possivelmente chegando a um plano melhor. Leia também:Solucionando problemas de desempenho de consulta ruim:dobra constante e avaliação de expressão durante a estimativa de cardinalidade .
@Martin Smith
Você pode executar esta consulta:
set nocount on;
declare @known int;
select @known = count(*) from sysobjects;
declare @cnt int = @known;
while @cnt = @known
select @cnt = count(*) from sysobjects where getdate()=getdate()
select @cnt, @known;
No meu caso, após 22 segundos, ele atingiu o caso limite e o loop foi encerrado. O importante é que o loop saiu com
@cnt
zero . Seria de esperar que se o getdate()
for avaliado por linha, obteremos um @cnt diferente da contagem correta de @known, mas não 0. O fato de @cnt ser zero quando o loop existir mostra cada getdate()
foi avaliado uma vez e, em seguida, o mesmo valor constante foi usado para cada filtragem WHERE de linha (nenhuma correspondente). Estou ciente de que um exemplo positivo não prova um teorema, mas acho que o caso é bastante conclusivo.