sql >> Database >  >> RDS >> Sqlserver

Optimaliseert SQL Server de DATEADD-berekening in de selectiequery?

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.



  1. Kortsluitlogica evaluatie-operators

  2. MySql:alleen-lezen opties verlenen?

  3. SQL gebruiken als een xlookup

  4. selecteer uit de ene tabel, tel vanaf een andere waar id is gekoppeld