Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Bisakah seseorang menjelaskan perbedaan antara dua pertanyaan?

getdate() adalah runtime fungsi konstan dan hanya dievaluasi sekali per referensi fungsi, itulah sebabnya

SELECT GETDATE()
FROM SomeBigTable

akan mengembalikan hasil yang sama untuk semua baris terlepas dari berapa lama kueri dijalankan.

Namun ada perbedaan antara keduanya. Karena yang pertama menggunakan variabel dan rencana dikompilasi sebelum variabel ditetapkan ke SQL Server akan (jika tidak ada kompilasi ulang) mengasumsikan bahwa 30% dari baris akan dikembalikan. Tebakan ini dapat menyebabkannya menggunakan rencana yang berbeda dari kueri kedua.

Sesuatu yang perlu diingat dengan menggunakan GETDATE() langsung dalam filter adalah bahwa ia mengevaluasi GETDATE() pada waktu kompilasi dan setelah itu selektivitas dapat berubah secara dramatis tanpa kueri atau perubahan data untuk memicu kompilasi ulang. Dalam contoh di bawah ini terhadap tabel 1.000 baris, kueri yang menggunakan variabel mengarah ke rencana dengan perkiraan 300 baris dan pemindaian tabel penuh sedangkan kueri dengan panggilan fungsi yang disematkan memperkirakan 1 baris dan melakukan pencarian bookmark. Ini akurat pada putaran pertama tetapi pada putaran kedua karena berlalunya waktu sekarang semua baris memenuhi syarat dan akhirnya melakukan 1.000 pencarian acak seperti itu.

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tweet Lucu Tentang Kehidupan DBA

  2. SSRS memilih hasil berdasarkan daftar yang dibatasi koma

  3. Prosedur atau fungsi !!! memiliki terlalu banyak argumen yang ditentukan

  4. Gunakan FILEGROUP_ID() untuk Mengembalikan ID Filegroup di SQL Server

  5. Permintaan SQL untuk menemukan gaji tertinggi ke-N dari tabel gaji