SQL Server-functies die worden beschouwd als runtime-constanten
worden slechts één keer beoordeeld. GETDATE()
is zo'n functie, en DATEADD(..., constant, GETDATE())
is ook een looptijdconstante. Door de eigenlijke functieaanroep in de query te laten, laat je de optimizer zien welke waarde daadwerkelijk zal worden gebruikt (in tegenstelling tot een variabele waarde sniff) en dan kan het zijn kardinaliteitsschattingen dienovereenkomstig aanpassen, mogelijk met een beter plan.
Lees ook dit:Problemen oplossen Slechte queryprestaties:constant vouwen en expressie-evaluatie tijdens kardinaliteitsschatting .
@Martin Smith
U kunt deze zoekopdracht uitvoeren:
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;
In mijn geval raakte het na 22 seconden het grensgeval en verliet de lus. Het belangrijkste is dat de lus werd afgesloten met @cnt
nul . Je zou verwachten dat als de getdate()
wordt geëvalueerd per rij, dan krijgen we een @cnt die verschilt van de juiste @known count, maar niet 0. Het feit dat @cnt nul is wanneer de lus bestaat, toont elke getdate()
werd eenmaal geëvalueerd en vervolgens werd dezelfde constante waarde gebruikt voor elke rij WHERE-filtering (geen overeenkomst). Ik ben me ervan bewust dat één positief voorbeeld geen stelling bewijst, maar ik denk dat de zaak overtuigend genoeg is.