[SQL SERVER][Performance] 善用 Fast N Hints

[SQL SERVER][Performance] 善用 Fast N Hints

我想大家都應該知道,如果查詢特性針對 Nonclustered Index有排序需求的話,

那麼你在設計該 Index 時就該考慮排序需求,

雖然盡量避免針對 Nonclustered Index排序(clustered Index存在邏輯排序較適合),

因為針對大型資料表進行排序操作將耗費大量系統資源(tempdb 和整體時間),

但現實世界中這是相當難避免的,昨天我處理一個大型成本查詢效能問題,

經過SQL Tuning 後查詢成本改善約150倍、整體時間改善約3倍,

而我個人覺得任何資料庫優化效益都不及調校一句高成本SQL來的高,

下面我大概模擬一下。

 

select LogDate,LoginId,LogMessage,LogLevel
from dbo.ap_log 
where LoginId in('sherry','papa','rico') 
order by LoginId

 

 

我先針對查詢SQL特性建立Nonclustered Index並考慮排序,然後執行該查詢。

image

整體時間(ms):281+8253=8534。logical reads:12824。

 

 image image

整體查詢成本:7.299。

 

執行計畫中看到雖然查詢有正確使用索引搜尋資料,

但我改寫SQL後(使用 fast 1 hints) ,更進一步降低查詢成本和時間。

 

改寫SQL加入option(fast 1)

select LogDate,LoginId,LogMessage,LogLevel
from dbo.ap_log 
where LoginId in('sherry','papa','rico') 
order by LoginId
option(fast 1)

 

image

整體時間(ms):313+7559=7872。logical reads:12824。

 

image image

整體查詢成本:0.003。

可以看到索引搜尋作業估計的資料列數目=1,

透過更改基數來改善查詢最佳化整體成本。

 

結論:

可以看到整體查詢成本改善 2433 倍,整體時間改善約1.08倍,

強烈建議加上option(fast 1) 提示改善整體查詢成本並減少回覆時間。

 

補充:

今天朋友問竟然Fast 1那麼好,為什麼SQL Server不乾脆內建:

我回答:由於提式是覆寫查詢最佳化程式過程,所以使用提示要注意2點

1.一開始使用提式可能獲得改善,但長時間下來隨者資料量的變動,可能會造成反效果,

   所以使用提示的SQL都要定期追蹤並調整。

2.更新任何資料庫hotfix可能會改變查詢最佳化程式的行為,可能存取最佳化路徑有所改變,

所以SQL Server團隊乾脆讓使用者自行決定。

 

那麼 N 這數字要用什麼呢?有什麼方法來評估嗎?

我回答:N這個數字要看查詢特性的資料量大小,假設一開始查詢的量有10萬筆,

那可以先測試 1 ,如果10萬筆結果集都有完整返回給使用者,且整體時間有所改善的話,那 N=1 就算合適,

但資料量隨者時間成長,假設一年後查詢量已變成200萬筆,那麼 N=1 可能就會造成反效果,

這時就要調整 N=10 、20...直到確認結果集完整返回且整體時間有所改善為止。

 

結論:使用提示的SQL都要定期追蹤並調整。

 

 

參考

查詢提示 (Transact-SQL)