我正在一個大約1000萬行的大表上進行搜索。我想指定開始日期和結束日期,並返回在這些日期之間創建的表中的所有記錄。在DATETIME列上的DATETIME搜索謂詞比字符串文字謂詞慢得多
這是一個直接的查詢:
declare @StartDateTime datetime = '2016-06-21',
@EndDateTime datetime = '2016-06-22';
select *
FROM Archive.dbo.Order O WITH (NOLOCK)
where O.Created >= @StartDateTime
AND O.Created < @EndDateTime;
創建是具有非聚集索引中的DATETIME列。
此查詢大約需要15秒才能完成。
但是,如果我稍微修改查詢,如下所示,則僅需1秒鐘返回相同的結果:
declare @StartDateTime datetime = '2016-06-21',
@EndDateTime datetime = '2016-06-22';
select *
FROM Archive.dbo.Order O WITH (NOLOCK)
where O.Created >= '2016-06-21'
AND O.Created < @EndDateTime;
唯一的變化是用一個字符串替換@StartDateTime
搜索謂詞。查看執行計劃,當我使用@StartDateTime
時,它執行了索引掃描,但是當我使用字符串時,它執行了索引查找,速度提高了15倍。
有誰知道爲什麼使用字符串文字是如此之快?
我原以爲DATETIME列和DATETIME變量之間的比較比將列與日期的字符串表示進行比較要快。我嘗試刪除並重新創建創建列上的索引,它沒有任何區別。我注意到我在生產系統上得到了類似於測試系統上的結果,所以奇怪的行爲似乎並不特定於特定的數據庫或SQL Server實例。
答案是關係到SQL Server如何識別查詢中的變量。如果SQL在運行查詢之前無法知道該變量是什麼,它可能無法使用緩存計劃或無法有效猜測新的計劃 –
有一篇關於該主題的好文章,我認爲您會發現它有幫助:[SQLmag - 優化變量和參數](http://m.sqlmag.com/t-sql/optimizing-variables-and-parameters) –
@clifton_h:對不起,它需要一段時間,一直忙於工作。您鏈接的那篇文章回答了我的問題。如果您想將您的評論轉換爲答案,我會接受它。 –