iT邦幫忙

0

MS SQL問題

  • 分享至 

  • xImage

目前資料表A中,裡面有7百多萬的資料,且已針對該欄位建立索引
在MS SQL中,我寫了兩段寫法

SELECT TOP 10000 * FROM 資料表A WHERE 欄位1>='20240313' AND 欄位1<='20240313'

↑執行時間不到1秒

DECLARE @DATES CHAR(8)
SET @DATES = '20240313'

SELECT TOP 10000 
	* 
FROM 資料表A
WHERE 欄位1>=@DATES AND 欄位1<=@DATES

↑執行時間38秒

然而我將SQL改成

DECLARE @DATES CHAR(8)
SET @DATES = '20240313'

SELECT TOP 10000 
	* 
FROM 資料表A
WHERE 欄位1>=@DATES AND 欄位1<=@DATES
OPTION(RECOMPILE)

↑執行時間不到1秒

想詢問各位大大,這個原因是如何產生的?為何加了OPTION(RECOMPILE)卻可以改善此問題?

(如上述資訊量不夠,還煩請告知)

neofancy iT邦新手 5 級 ‧ 2024-03-14 15:11:48 檢舉
https://blog.csdn.net/josjiang1/article/details/80671739
這篇文章的描述與您的狀況相似,可以參考一下唷
報告,是的,我是查詢這篇文章解開我目前所發生的問題,但是想了解這個問題怎麼發生的。
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
0
厚厚
iT邦新手 1 級 ‧ 2024-03-14 16:00:38
最佳解答

依據neofancy的貼文,所以有去看執行計畫的確有差異嗎?
如果的確有差異,那問題就在什麼導致SQL判斷有差異,可能原因有

參數嗅探 Parameter Sniffing 導致使用到不是較優的執行計劃

統計資料 : SQL會使用統計資料來建立可改善查詢效能的查詢計劃,所以更新資料表的統計資料試試 EXEC sp_updatestats
https://learn.microsoft.com/zh-tw/sql/relational-databases/statistics/statistics?view=sql-server-ver16

看更多先前的回應...收起先前的回應...

報告,這個有試過【EXEC sp_updatestats】,但是查詢的結果跟上面描述的一樣。

厚厚 iT邦新手 1 級 ‧ 2024-03-14 16:09:03 檢舉

那應該就是參數嗅探的問題了,你可以GOOGLE一些大神前輩的處理方式

neofancy iT邦新手 5 級 ‧ 2024-03-14 16:46:01 檢舉

有找到另外兩篇文章,裡面所述有點像是有無帶參數而影響,如同厚厚所言,然而加上OPTION(RECOMPILE)之後,會重新編譯,執行上會等同於不帶參數的模式,所以會比較快

https://www.cnblogs.com/wy123/p/6262800.html
https://sqlperformance.com/2013/08/t-sql-queries/parameter-sniffing-embedding-and-the-recompile-options

提供參考

厚厚 iT邦新手 1 級 ‧ 2024-03-14 16:50:15 檢舉

因為參數嗅探就是因為參數化才會發生的問題,所以如果有因為參數"值"導致搜尋結果數會有很大差異,那就很有可能是參數嗅探產生的執行計畫差異

厚厚 iT邦新手 1 級 ‧ 2024-03-14 16:51:48 檢舉

OPTION(RECOMPILE)就是不去找以前的執行計畫,所以就不會有執行計畫差異的問題了

了解,感謝大大們的回覆。

0
zza6312
iT邦新手 2 級 ‧ 2024-03-15 07:12:59

基本上每個 Query 下提供的條件其實應該不同,
但執行第一次查詢時,
Query engine 會產生第一個條 Query Plane,
並且針對你首次查詢時所下的條件內容作優化,

但問題來了,
你接下來的每次查詢他都會套用第一次查詢產生出來的 Query Plane,
也就是說不再針對你新的查詢請求再重新作一次優化的參數,

但你加上 OPTION(RECOMPILE) 時,
因為要重新 Compile,
所以 Query Engine 會再產生一個全新適用你此次查詢的優化參數,
因此會特別快

了解,感謝您的回覆。

1
SunM0on
iT邦新手 5 級 ‧ 2024-03-15 10:35:53

OPTION(RECOMPILE)是重新編譯你的語句,但要記得,重新編譯SQL語句本身也是會產生開銷的

重新編譯後,你可以理解為預處理
舉個例子好了
select * from xxx where id = @id
select * from xxx where id = 1
這是帶參數跟不帶參數的,@id執行週期需要做其他處理,最後才會與select * from xxx where id =結合產生執行語句
select * from xxx where id = 1,這件事情是不用在執行週期完成就可以產生的執行語句
select * from xxx where id = @id OPTION(RECOMPILE)則是在編譯期就轉成像select * from xxx where id = 1語句
簡單來說 就是編譯期完成了執行期要做的事情(當然,recompiler是另外的開銷是另一回事)

了解,感謝您的回覆。

我要發表回答

立即登入回答