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

Kan nogen forklare forskellen mellem to forespørgsler?

getdate() er en runtime konstant funktion og evalueres kun én gang pr. funktionsreference, hvorfor

SELECT GETDATE()
FROM SomeBigTable

vil returnere det samme resultat for alle rækker, uanset hvor lang tid det tager at køre forespørgslen.

Der er dog forskel på de to. Da den første bruger en variabel, og planen kompileres, før variablen tildeles SQL Server, vil (i mangel af en rekompilering) antage, at 30% af rækkerne vil blive returneret. Dette gæt kan få den til at bruge en anden plan end den anden forespørgsel.

Noget at huske på ved brug af GETDATE() direkte i et filter er, at det evaluerer GETDATE() på kompileringstidspunktet, og derefter er det muligt for selektiviteten at ændre sig dramatisk, uden at hverken forespørgslen eller dataene ændres for at udløse en rekompilering. I eksemplet nedenfor mod en tabel med 1.000 rækker, fører forespørgslen ved hjælp af en variabel til en plan med anslået 300 rækker og en fuld tabelscanning, hvorimod forespørgslen med funktionskaldet indlejret anslår 1 række og foretager et bogmærkeopslag. Dette er nøjagtigt på den første kørsel, men på den anden kørsel på grund af tidens gang kvalificerer alle rækker sig nu, og det ender med at lave 1.000 sådanne tilfældige opslag.

USE tempdb;

CREATE TABLE [myTable]
(
CreatedDate datetime,
Filler char(8000) NULL
)

CREATE NONCLUSTERED INDEX ix ON [myTable](CreatedDate)

INSERT INTO [myTable](CreatedDate)
/*Insert 1 row that initially qualifies*/
SELECT DATEADD(D,-2001,getdate())
UNION ALL
/*And 999 rows that don't initially qualify*/
SELECT TOP 999 DATEADD(minute,1, DATEADD(D,-2000,getdate()))
FROM master..spt_values

EXEC('
DECLARE @myDate DATETIME = DATEADD(D,-2000,getdate())
SELECT * 
FROM [myTable]  
WHERE CreatedDate <= @myDate
')

EXEC('
SELECT * 
FROM [myTable]  
WHERE CreatedDate <= DATEADD(D,-2000,getdate())
')

RAISERROR ('Delay',0,1) WITH NOWAIT

WAITFOR DELAY '00:01:01'

EXEC('
DECLARE @myDate DATETIME = DATEADD(D,-2000,getdate())
SELECT * 
FROM [myTable]  
WHERE CreatedDate <= @myDate
')

EXEC('
SELECT * 
FROM [myTable]  
WHERE CreatedDate <= DATEADD(D,-2000,getdate())
')

DROP TABLE [myTable]


  1. Vælg alle indstillingsværdier php mysql

  2. Få Max værdi og tilsvarende kolonne

  3. MySQL eksporterer INTO OUTFILE --secure-file-priv fejl ved brug af set mappe

  4. Sådan anvender du farver i powershell-output