如何解決 SQL Server 中的最大工作線程問題

Avilas

在我們討論相關的性能問題之前最大工作線程數(MWT),讓我們了解一下隨鑽測量做。隨鑽測量是可用於 SQL Server 的工作線程,並且使用本機 Windows 線程 SQL Server 同時並行處理多個任務。例如,數據庫檢查點、網絡層進程、處理事務處理等。默認值為 0。0 值允許 SQL Server 根據服務器資源動態生成線程。它適用於全球大多數 SQL Server 部署。為了提高性能,有時手動增加 MWT 值會有所幫助。在這篇文章中,我將討論如何解決 SQL Server 中的最大工作線程問題。

僅當 SQL Server 非常繁忙、用戶並發性較高且啟用了 SQL Server Always On、複製服務等附加功能時,您才會用完 MWT。根據 SQL Server 版本(32 位或 64 位)和處理器核心,SQL Server 生成工作線程池來服務用戶請求。以下是硬數據的快速瀏覽。

了解更多:2019 年如何在 Azure 存儲上進行 SQL Server 混合備份到 URL

CPU 核心數 較舊的 32 位服務器 最新 64 位服務器
最多 4 個處理器 256 第512章
八核 8 處理器 288 第576章
16 個處理器 第352章 704
32 個處理器 第480章 960
64 個處理器 第736章 第1472章
128 個處理器 4224 4480
256 個處理器 8320 8576

MWT 配置選項不包括用於 Always On 可用性組和數據庫鏡像的線程。

使用以下查詢找出哪些系統任務導致產生額外的工作線程:

SELECT  
s.session_id,  
r.command,  
r.status,  
r.wait_type,  
r.scheduler_id,  
w.worker_address,  
w.is_preemptive,  
w.state,  
t.task_state,  
t.session_id,  
t.exec_context_id,  
t.request_id  
FROM sys.dm_exec_sessions AS s  
INNER JOIN sys.dm_exec_requests AS r  
    ON s.session_id = r.session_id  
INNER JOIN sys.dm_os_tasks AS t  
    ON r.task_address = t.task_address  
INNER JOIN sys.dm_os_workers AS w  
    ON t.worker_address = w.worker_address  
WHERE s.is_user_process = 0;

如何使用 T-SQL 更改最大工作線程數

USE AdventureWorks2016 ;  
GO  
EXEC sp_configure 'show advanced options', 1;  
GO  
RECONFIGURE ;  
GO  
EXEC sp_configure 'max worker threads', 1000 ;  
GO  
RECONFIGURE;  
GO

有時,減少工作線程數可以提高性能

數據庫鏡像和 Always On 可用性組的最大工作線程最佳實踐

  • 為了避免 MWT 耗盡,請不要創建超過 10 個可用性組和 100 個數據庫。這意味著每個可用性組有 10 個 DB。這是建議,而不是硬性限制。
  • 如果 MWT 耗盡,請添加其他 CPU 或虛擬 CPU(如果是虛擬機)以增加 MWT 計數。請參閱上表以供參考。
  • 在同一服務器上創建另一個實例來改進 MWT 不會提高性能。
  • 運行鏡像和可用性組的數據庫進行過多的數據庫整合可能會導致 MWT 耗盡。
  • 始終在 AG 上實施之前計算最大 MWT 並廣泛測試系統。

如何計算 MWT 計數?

MWT = {512 + ((Number of CPU Cores - 4) * 16)} = Result

如何計算最大工作線程使用率

select scheduler_id,current_tasks_count,

current_workers_count,active_workers_count,work_queue_count    

from sys.dm_os_schedulers    

where status = ‘Visible Online’

哪個系統任務正在使用 MWT 線程的詳細信息

select is_preemptive,state,last_wait_type,count(*) as NumWorkers from sys.dm_os_workers    

Group by state,last_wait_type,is_preemptive    

order by count(*) desc

Microsoft 的官方在線資源