SQL Server-funktioner som anses vara körtidskonstanter
utvärderas endast en gång. GETDATE()
är en sådan funktion, och DATEADD(..., constant, GETDATE())
är också en körtidskonstant. Genom att lämna det faktiska funktionsanropet inuti frågan låter du optimeraren se vilket värde som faktiskt kommer att användas (i motsats till en variabelvärdessniff) och sedan kan den justera sina kardinalitetsuppskattningar därefter, eventuellt komma med en bättre plan.
Läs även detta:Felsökning av dålig frågeprestanda:konstant vikning och utvärdering av uttryck under kardinalitetsuppskattning .
@Martin Smith
Du kan köra den här frågan:
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;
I mitt fall träffade den gränsfallet efter 22 sekunder och slingan gick ut. Det viktiga är att loopen avslutades med @cnt
noll . Man skulle förvänta sig att om getdate()
utvärderas per rad så skulle vi få en @cnt som skiljer sig från det korrekta @kända antalet, men inte 0. Det faktum att @cnt är noll när slingan finns visar varje getdate()
utvärderades en gång och sedan användes samma konstanta värde för varje rad WHERE-filtrering (matchar ingen). Jag är medveten om att ett positivt exempel inte bevisar ett teorem, men jag tror att fallet är tillräckligt avgörande.