首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server sys.dm_os_waiting_tasks 實戰解析(中):並行等待爆炸成因與 Task/Worker/Scheduler 模型詳解

     編輯:關於SqlServer

承接上篇發現 sys.dm_exec_requests 在並行查詢中無法顯示真實等待 (僅回報 CXPACKET),本文深入剖析為何 4 DOP 並行查詢會產生 21 條等待記錄,並完整定義 Scheduler、Worker、Task、Yielding 四大 SQLOS 核心物件與運作機制。

現象回顧:4 DOP 產生 21 條等待

  • 去重 task_address 僅 9 個唯一 Task。
  • 包含:4 個掃描 Worker、4 個消費者 Worker、1 個協調者。
  • 等待類型:LCK_M_S (鎖等待)、CXPACKET (交換港等待)、EXCHANGE (協調)。

SQLOS 任務調度四大核心定義

Scheduler (排程器) — 邏輯 CPU

  • 每個邏輯 CPU (含超執行緒) 對應一個 Scheduler。
  • 同一時間僅一個 Worker 擁有 Scheduler 執行權,其餘在 Runnable Queue 排隊。
  • 不綁定物理 CPU,除非設定 affinity mask。

Worker (工作者) — 執行緒載體

  • 1:1 對應 Windows Thread (或 Fiber 模式下的 Fiber)。
  • 固定綁定一個 Scheduler,由 SQLOS 管理生命週期 (建立/回收)。
  • 最大 Worker 數預設值:
CPU 核心數32-bit64-bit
≤4256512
8288576
16352704
32480960

Task (任務) — 最小工作單元

  • 一個 Batch (GO 分隔) = 一個 Task。
  • Task 佔用 Worker 直到完成或主動等待 (鎖、I/O、同步)。
  • 等待時不釋放 Worker (非搶占式),導致執行緒阻塞。

Yielding (主動讓步) — 非搶占式調度核心

Worker 定期檢查執行時間,主動歸還 Scheduler,關鍵觸發點:

  1. 讀取資料頁前:已執行 > 4ms。
  2. 每排序 64KB。
  3. 編譯過程中。
  4. 用戶端消費緩慢。
  5. Batch 內每句結束。

此設計避免長佔用 CPU、降低 Context Switch。

手繪關係圖

並行調度實況 (4 DOP、4 Scheduler)

  • 9 Task → 9 Worker → 分佈於 4 Scheduler。
  • 每 Scheduler 平均 2-3 Worker 輪流執行。
  • 掃描 Worker (Producer) 產出資料 → 交換港 → 消費者 Worker (Consumer) 接收。
  • 消費者在資料到達前處於 CXPACKET 等待,非閒置。

為何 sys.dm_exec_requests 失效?

  • 僅回報協調者 Task 的 CXPACKET 等待。
  • blocking_session_id = 0 掩蓋真實阻塞者。
  • 串行計劃時兩視圖一致,並行時必須用 sys.dm_os_waiting_tasks。

下篇預告

實戰驗證:雙表同時鎖定,觀察並行掃描順序;Union All 為何無法多支同時執行?持續監控腳本捕捉完整等待鏈。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved