2016-10-11 67 views
11

返回我有一個表有兩個值:SQL變量需要更長的時間比靜態值

ciid, businessdate 

CIID是主鍵,並具有自動遞增開啓。 businessdate(日期時間)由另一個進程插入。

給出以下查詢:

select top(1) ciid, businessdate 
from checkitemsales 
where businessdate='10/9/16 00:00:00:000' 

這隻需要1.2秒返回,而這個查詢:

declare @var1 datetime 

set @var1='10/9/16 00:00:00:000' 

select top(1) ciid, businessdate 
from checkitemsales 
where businessdate = @var1 

需要5.6秒返回。

誰能告訴我我做錯了什麼?

+1

嘗試運行查詢多次,看是否定時是一致的。這兩者應該可能具有相同的性能。 –

+0

當然方法2比方法1需要更長的時間,因爲每次查詢數據時,都需要參考這個「set @ var1 = '10/9/16 00:00:00:000' 」data – KyLim

+0

檢查查詢計劃。也許在第二個查詢的緩存中有一個錯誤的計劃。 – Blorgbeard

回答

1
declare @var1 datetime 

set @var1='10/9/16 00:00:00:000' 

select top(1) ciid, businessdate 
from checkitemsales 
where (businessdate = @var1) option (recompile) 

試試這個,讓我知道結果,它可能會更快

+0

消息156,級別15,狀態1. 關鍵字'選項'附近的語法不正確。 (第7行) – kloodge

+0

DECLARE @ var1的日期時間 組@ var1的= '10 /一十六分之九00:00:00:000' 選擇(1)頂部CIID,businessdate 從checkitemsales 其中(businessdate = @ var1的)選項(重新編譯) 導致不到一秒! – kloodge

+0

@ kloodge第二隻 - 哈哈哈,盡我所能 – KyLim

4

這就是所謂的參數執行查詢或使用存儲過程的參數時,嗅探

。在編譯期間,傳遞給參數的值將被評估並用於創建執行計劃。該值也與執行計劃一起存儲在計劃緩存中。該計劃的未來執行將重新使用與該參考值一起編譯的計劃。

您可以通過各種方法避免這種情況。一個是

重新編譯

您可以將option(Recompile)添加到查詢,以便每次查詢編譯一個新的執行計劃會產生

select top(1) ciid, businessdate 
from checkitemsales 
where businessdate = @var1 
OPTION (RECOMPILE); 

缺點

  • 查詢頻繁運行。
  • CPU資源有限。
  • 查詢性能有些差異是可以接受的。

其他方法

  • 優化對於價值
  • 優化未知
  • 例外

檢查的所有上述方法的詳細信息,下面的文章

sp_BlitzCache™ Result: Parameter Sniffing

Parameter Sniffing

0

你可以試試這個方法:

declare @var1 datetime 
set @var1='10/9/16 00:00:00:000' 

declare @cmd varchar(max) = 'select top(1) ciid, businessdate 
from #table 
where businessdate = ''' + CONVERT(VARCHAR(10), @var1, 1) + ' ' + convert(VARCHAR(12), @var1, 114) + '''' 

EXEC (@cmd)