sql >> Database teknologi >  >> RDS >> Sqlserver

Optimerer SQL Server DATEADD-beregning i udvalgte forespørgsler?

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.



  1. Hurtigt indlæg om SQLite UPSERT og den nye RETURNING-klausul.

  2. Laravel PDOException SQLSTATE[HY000] [1049] Ukendt database 'forge'

  3. Sådan fjerner du dublerede kolonner fra join i SQL

  4. Hvordan vælger man række efter primærnøgle, én række 'ovenfor' og en række 'under' ved anden kolonne?