2014-01-29 35 views
1

我正在使用SQL Server 2008 R2數據庫,其中包含一個表,其中包含的行數爲十億行。我想在過去24小時內得到一個列的不同的值,所以我做了這個(查詢1):受變量阻礙的SQL Server索引性能

SELECT DISTINCT SomeField FROM SomeTable WHERE CreatedOn > '2014-01-28 12:24:00' 

注有上CreatedOn的指數,但它不包括SomeField 。這立即返回。現在,由於這是一個查詢我經常跑,我決定把它動態的,所以我把它改爲(查詢2):

DECLARE @StartDate DATETIME = DATEADD(DAY, -1, GETDATE()) 
SELECT DISTINCT SomeField FROM SomeTable WHERE CreatedOn > @StartDate 

我感到驚訝的是這個查詢花費很長的時間。 (我一分鐘左右後停止它。)然後我試圖把變量內嵌像這樣(查詢3):

SELECT DISTINCT SomeField FROM SomeTable WHERE CreatedOn > DATEADD(DAY, -1, GETDATE()) 

這是快速試。查看執行計劃,查詢1和3是相同的並使用索引查找。但查詢2做索引掃描,並建議我缺少包括SomeField在內的CreatedOn上的索引。

爲什麼檢查變量會突然改變索引的有效性?

+1

[閱讀此](http://msmvps.com/blogs/robfarley/archive/2010/01/22/sargable-functions-in-sql-server.aspx)瞭解更多信息。 –

回答

1

最可能的原因是,當一個值被硬編碼時,編譯器可以使用這些統計信息來找出最佳查詢來運行。當使用變量時,它不會並且必須執行掃描。如果您嘗試創建一個存儲過程,並且以這種方式運行,那麼服務器可以使用「parameter sniffing」,您可能會看到更好的性能。

你可以找到一些其他人誰已經看到這個問題的更多信息here,herehere