[SQL SERVER][Performance]CPU Bottleneck(一)--縮小範圍

[SQL SERVER][Performance]CPU Bottleneck(一)--縮小範圍

前言

一般來說CPU Bottleneck很容易觀察,如果SERVER CPU持續15分鐘維持70~80%以上(並非突發性),

然後系統效能逐漸降低,那麼系統可能存在CPU Bottleneck,

但要找出CPU Bottleneck真正兇手並不容易,

因為SQL SERVER 所有動作幾乎都會使用到CPU資源,

如執行查詢、記憶體資料搬到硬碟(switch)..等,

如果SERVER又存在多種服務(非服務單一SQL SERVER ),又或是身處虛擬環境的話

那麼複雜度將提高不少,

因為CPU壓力來源可能來自AP或其他服務(並非SQL SERVER造成),

而我個人最常見就是記憶體不足(過度Switch)和不正確的平行化查詢處理(不良查詢和不正確索引),

導致CPU持續維持90%以上,不幸的是我沒有最直接的方法來驗證Server Bottleneck主因是CPU 資源不足,

也沒有很快的方法找出造成CPU Bottleneck主因,所以我只能夠縮小範圍,從中逐一驗證假設,抽絲剝繭找出兇手。

 

一.縮小範圍

我主要用的兩個工具分別是效能監視器(Performance Monitor)和DMV(該資料為累積),至於 SQL Trace我個人比較少用。

效能監視器

效能監視器使用方式可以參考我很久以前的文章[SQL SERVER][Performance]找出硬體Bottleneck

我大概會加入以下三個主要效能計數器

Processor/ %Privileged Time:CPU花費在執行WINDOWS系統核心命令(system kernel commands)時間百分比。

Processor/ %User Time:CPU花費在執行使用者命令,如SQL SERVER I/O請求。

Process (sqlservr.exe)/ %Processor Time:每一個處理序包含所有執行序所花費CPU執行時間總和。

但如果你想要知道是那些事件用掉多少CPU資源的,可能就需要再額外其他效能計數器。

 

ps:如果身處VM的話,ProcessorTime資源分配是依照虛擬機上的資源,並非實體機上的資源,

如果VM上的CPU分配很少資源的話,那麼VM上的ProcessorTime將很高,須注意誤判情況。

 

DMV

透過幾個DMV相關CPU統計值,輔助我們調查高CPU的原因

sys.dm_exec_query_statssys.dm_exec_sql_text: 查詢高成本CPU語法

參考[SQL SERVER][TSQL]獲取各種高成本查詢語法

 

sys.dm_os_waiting_tasks : 查詢現階段所等待任務。

sys.dm_os_wait_stats :  傳回執行中之執行緒所遇到之所有等候的相關資訊。 

您可以使用這份彙總檢視來診斷 SQL Server 的效能問題,以及特定查詢和批次的效能問題。

主要可以透過以下三個等待類型來調查CPU壓力。

image

一般來說CMEMTHREAD類型不常見,就算有也應該整體等待時間很低,

如果等待時間很高,表示系統存在過多動態或ad hoc查詢,

因為過高的快取大小可能會造成過度使用CPU資源。

 

image

等待類型出現CXPACKET 可能表示查詢誤用平行化處理,

採取平行化處理時機,應該是接受少量查詢並含有大量資料才是,

當OLTP存在很多小量查詢或交易時,使用平行化處理反而會影響效能(降低吞吐量)。

 

image

當等待類型出現SOS_SCHEDULER_YIELD且整體等待時間相當高的話,

那就表示有高密集的CPU查詢(平行化處理),代表就要優化調校相關高成本CPU查詢語法,

或是SERVER的CPU資源真的不足夠,系統如果有足夠的CPU資源可以執行相關任務的話,

該類型的等待時間應該是相當低的,無須等待其他資源(disk I/O, locks, latches, memory grants..等)。

 

 

快速驗證CPU壓力

SELECT SUM(signal_wait_time_ms) AS TotalSignalWaitTime ,
( SUM(CAST(signal_wait_time_ms AS NUMERIC(20,2)))
/ SUM(CAST(wait_time_ms AS NUMERIC(20,2))) *100 )
AS PercentageSignalWaitsOfTotalTime
FROM  sys.dm_os_wait_stats

如果SignalWaitTime 明顯大於SignalWaitsOfTotalTime的話,

這可以證明有大量密集使用CPU的查詢(表示該任務正再等待一個長時間資源),

有可能需要優化調校這些查詢,或者是Server需要更多的CPU資源。

 

第一部分先寫到這裡,後面我將抽空補上找出CPU Bottleneck的一些方法和常見原因,

總而言之,你一定要了解過度使用CPU資源的後果是相當嚴重的。

 

 

參考

[SQL SERVER][Performance]找出硬體Bottleneck