[SQL SERVER][Performance]CPU Bottleneck(二)--常見原因
第一部分我們可以透過一些方法來縮小造成高CPU的可能原因範圍,
第二部分將說明個人常見造成高CPU幾個原因。
一、不良SQL(不符合SARG)
這一點應該是老生常談了,但這原因卻永遠在第一順位,
簡單來說SQL符合SARG就可以使用 index seek(索引正確前提下),反之可能就會使用index scan,
但某些情況下index scan 運算子會優於 index seek,這取決於你查詢的資料列數(基數)是否接近整個資料表列數。
還有欄位比較都是直接比較,沒有反向操作、函數或任何運算...等這些都符合SARG,
所以SQL Tuning第一步永遠是修正不符合SARG格式的SQL。
[作品][RUN!PC]SQL Server2008查詢效能調校
二、遺漏/不正確索引
遺漏索引會造成高CPU使用量,但我最常見是不正確索引所導致(使用錯誤索引比沒建立索引來的嚴重),
開發人員寫完一句符合商業資料邏輯SQL後,往往都會忘記建立該SQL索引,
當然不是一定都要對每一句SQL建立索引,但要掌握一個基本建立索引原則,
大海撈針就得要思考索引怎麼設計,好比我公司一個月平均門禁刷卡資料約9萬筆,
當你前端WEB要顯示個人每日刷卡時間時,你在寫這句SQL時,同時也要思考索引該如何設計,
使用正確的索引才能有效降低CPU使用量。
三、隱式轉換
我常見開發人員不注重欄位資料類型,所以SQL語句where or from 中充滿不同資料類型的比較,
你要知道SQL SERVER無法比較不同資料類型,但SQL SERVER又為了可以正確執行,
所以查詢優化程式會偷改你原本的SQL(須確定where 和 join條件都正常才改寫),
幫你把低階資料類型自動轉換為高階資料類型,但這樣就造成該SQL不符合SARG格式(where 使用函數),
也意味將使用更多的CPU資源來擷取資料。
[SQL SERVER][Performance] 注意隱示轉換
[SQL SERVER][Performance] 注意隱示轉換 Part2
四、過時統計值
大部分常見都是因為統計值錯誤,造成執行計畫選擇適合較少資料列數的運算子,
好比nested loop joins and key lookups,但真正查詢的資料列數是相當龐大的,
這時執行計畫成本雖然不高,但該執行計畫效能卻是非常低的。
為了避免過時統計值發生,建議不要關閉資料庫自動更新統計值,
如果關閉自動更新統計值,那請建立一個job固定更新統計值。
五、參數探測
參數探測是發生在建立SP、function或參數查詢時,一般來說參數探測是好事,
但這裡會有一個問題發生,假設該輸入參數是提供給建立初始執行計畫使用,
那麼統計值可能就會依照輸入參數來計算,導致未來該SP、function或參數查詢的輸入參數改變時,
卻還是使用初始執行計畫(誤用執行計畫),而出現查詢低落、高CPU用量。
[SQL SERVER][Performance]淺談簡單和強制參數化
六、不當的平行處理
SQL SERVER被設計成可以使用多執行緒,平行處理的時機是少量查詢、大量資料,
如果查詢量多、資料量少,那平行查詢反而會拖垮效能(吞吐量降低),
一般來說只要序列畫執行計畫成本超過 cost threshold for parallelism 設定值,
並且SQL SERVER可用邏輯CPU大於1,且max degree of parallelism =0 or >1,
那麼SQL SERVER就會使用平行處理。
當平行處理使用適當的話,對那些高成本查詢可以獲得很高的改善且有利整體Server效能,
如果使用不當的話(如OLTP環境),將造成其他請求等待CPU資源(因為平行處理會使用多個CPU),
常常遇到不當的平行處理,我個人建議強制改變 max degree of parallelism(少動 cost threshold for parallelism),
如果 CXPACKET wait type 很高的話,那麼你的資料庫極有可能存在不當的平行處理。
[作品][RUN!PC]實測SQL Server 2008平行處理
上訴六大點相關解決方法,
你可以參考SQL PASS TW 3月分我主講的查詢調校不求人