[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並考慮排序,然後執行該查詢。
整體時間(ms):281+8253=8534。logical reads:12824。
整體查詢成本: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)
整體時間(ms):313+7559=7872。logical reads:12824。
整體查詢成本: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都要定期追蹤並調整。
參考