SQL調優日記--並行等待的原理和問題排查


概述

  今天處理項目,客戶反應數據庫在某個時間段,反應特別慢。需要我們提供一些優化建議。

 

現象

     由於是特定的時間段慢,排查起來就比較方便。直接查看這個時間段數據庫的等待情況。查看等待類型發現了大量的CXPAKET等待類型且等待時間長.

 

有的看官可能知道,出現這個等待類似時,可以適當降低最大並行度來解決。但是為什么這么做呢?降低並行度就一定可以解決問題嗎?

CXPAKET原理

 

  那什么是CXPAKET 等待呢。 當數據庫引擎分析查詢的開銷超過設定的閥值時,SQL SERVER會選擇並行執行。數據庫引擎會為這個請求創建多個任務。每個任務處理數據的一個子集。每個任務可以在一個分開的CPU/核上執行。請求主要使用生產-消費 隊列跟這些任務交互。如果這個隊列是空的,(即生產者沒有推入任何數據到這個隊列)。這個消費者必須暫停並且等待。相應等待類型就是CXPACKET 等待類型。顯示這個等待類型的請求 說明這個任務應該提供,但是沒有提供任何(或足夠)數據來消費。這些生產商任務反過來可能會暫停,等待一些其他類型的等待.

如下圖:索引掃描就是一個並行執行的動作。

 

打個比方

  客戶端程序就是老板,數據庫引擎是部門領導,老板發出一個要求(request),查看最近一年的銷售數據。領導一看這任務工作量大,一個人查太慢,要查到猴年馬月。果斷決定多派幾個人。一次最多可以派多少個攻城獅呢?(就取決於最大並行度)這里假設是4個。這就分配4個人 小李、小王、小張、小陳去完成。 那這一年的任務怎么分配呢? 以后再細說。 因為各種原因,其他人都做得了,小王還沒有完成。領導不可能拿着半成品的數據就去找老板,只能等着小王。這就是CXPACKET.

 

排查

 弄懂了CXPACKET的原理,那我們怎么來排查這類問題呢?首先,小王並不是偷懶,他的工作能力和其他人是相同的。所以,我們需要找出小王慢的原因,

 使用下面的腳本:

 
         

select r.session_id,
status,
command,
r.blocking_session_id,
r.wait_type as[request_wait_type],
r.wait_time as[request_wait_time],
t.wait_type as[task_wait_type],
t.wait_duration_ms as[task_wait_time],
t.blocking_session_id,
t.resource_description
from sys.dm_exec_requests r
LEFT join sys.dm_os_waiting_tasks t
on r.session_id = t.session_id
where r.session_id >=50
and r.session_id <> @@spid;

 

通過上面的語句我們找到,並行等待正在等待LCK_M_S.說明查詢是被其他的操作阻塞了。上面的問題是由於一個寫入語句引起的。這個語句是一個很簡單的插入動作,為什么寫入會這么慢呢。可以查看磁盤響應時間,,磁盤隊列

 

 發現都出奇的高。

建議

看來問題是由於磁盤本身引起的。給出如下的解決建議:

1.更換讀寫速度更快的磁盤

2.目前數據文件和日志文件在同一物理磁盤,分割開來

3.從業務出發。經過和客戶溝通后發現,這個表是操作日志表。每次做業務操作都會記錄日志。所以特別的大。

對應這樣的表,可以單獨建立文件夾組,文件,並把表放在單獨的磁盤,緩解IO壓力

4. 比如傳統機械磁盤IOPS往往是瓶頸,而吞吐量並不是,所以磁盤格式化的簇大小就比較重要,較大的簇可以減少IOPS瓶頸。

5.對於日志表,如果能改程序,在前端程序合並寫入,或者在情況允許的情況下開trace flag 610最小化日志寫入
6.整理磁盤碎片,另外合並&刪除日志表的索引減少寫入開銷也能起到一定作用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM