SQL Server-funktioner, der betragtes som runtime konstanter
vurderes kun én gang. GETDATE()
er sådan en funktion, og DATEADD(..., constant, GETDATE())
er også en køretidskonstant. Ved at forlade det faktiske funktionskald inde i forespørgslen lader du optimeringsværktøjet se, hvilken værdi der rent faktisk vil blive brugt (i modsætning til en variabel værdi-sniff), og derefter kan den justere sine kardinalitetsestimater i overensstemmelse hermed, muligvis komme med en bedre plan.
Læs også dette:Fejlfinding af dårlig forespørgselsydeevne:Konstant foldning og udtryksevaluering under kardinalitetsestimat .
@Martin Smith
Du kan køre denne forespørgsel:
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 mit tilfælde ramte den efter 22 sekunder grænsekassen, og løkken forlod. Det vigtige er, at løkken afsluttes med @cnt
nul . Man ville forvente, at hvis getdate()
evalueres pr. række, så ville vi få en @cnt forskellig fra den korrekte @kendte tælling, men ikke 0. Det faktum, at @cnt er nul, når sløjfen eksisterer, viser hver getdate()
blev evalueret én gang, og derefter blev den samme konstante værdi brugt for hver række WHERE-filtrering (matchede ingen). Jeg er klar over, at ét positivt eksempel ikke beviser en teorem, men jeg synes, sagen er afgørende nok.