SQL Server 2014的MAXDOP设置


8

我知道这个问题已经被问过很多次,并且也有答案,但是,我仍然需要更多有关该主题的指导。

以下是来自SSMS的CPU的详细信息:

中央处理器

以下是数据库服务器任务管理器中的“ CPU”选项卡:

CPU选项卡

MAXDOP通过以下公式保持设置为2:

declare @hyperthreadingRatio bit
declare @logicalCPUs int
declare @HTEnabled int
declare @physicalCPU int
declare @SOCKET int
declare @logicalCPUPerNuma int
declare @NoOfNUMA int
declare @MaxDOP int

select @logicalCPUs = cpu_count -- [Logical CPU Count]
    ,@hyperthreadingRatio = hyperthread_ratio --  [Hyperthread Ratio]
    ,@physicalCPU = cpu_count / hyperthread_ratio -- [Physical CPU Count]
    ,@HTEnabled = case 
        when cpu_count > hyperthread_ratio
            then 1
        else 0
        end -- HTEnabled
from sys.dm_os_sys_info
option (recompile);

select @logicalCPUPerNuma = COUNT(parent_node_id) -- [NumberOfLogicalProcessorsPerNuma]
from sys.dm_os_schedulers
where [status] = 'VISIBLE ONLINE'
    and parent_node_id < 64
group by parent_node_id
option (recompile);

select @NoOfNUMA = count(distinct parent_node_id)
from sys.dm_os_schedulers -- find NO OF NUMA Nodes 
where [status] = 'VISIBLE ONLINE'
    and parent_node_id < 64

IF @NoofNUMA > 1 AND @HTEnabled = 0
    SET @MaxDOP= @logicalCPUPerNuma 
ELSE IF  @NoofNUMA > 1 AND @HTEnabled = 1
    SET @MaxDOP=round( @NoofNUMA  / @physicalCPU *1.0,0)
ELSE IF @HTEnabled = 0
    SET @MaxDOP=@logicalCPUs
ELSE IF @HTEnabled = 1
    SET @MaxDOP=@physicalCPU

IF @MaxDOP > 10
    SET @MaxDOP=10
IF @MaxDOP = 0
    SET @MaxDOP=1

PRINT 'logicalCPUs : '         + CONVERT(VARCHAR, @logicalCPUs)
PRINT 'hyperthreadingRatio : ' + CONVERT(VARCHAR, @hyperthreadingRatio) 
PRINT 'physicalCPU : '         + CONVERT(VARCHAR, @physicalCPU) 
PRINT 'HTEnabled : '           + CONVERT(VARCHAR, @HTEnabled)
PRINT 'logicalCPUPerNuma : '   + CONVERT(VARCHAR, @logicalCPUPerNuma) 
PRINT 'NoOfNUMA : '            + CONVERT(VARCHAR, @NoOfNUMA)
PRINT '---------------------------'
Print 'MAXDOP setting should be : ' + CONVERT(VARCHAR, @MaxDOP)

我仍然看到与的相关高等待时间CXPACKET。我正在使用下面的查询来做到这一点:

WITH [Waits] AS
(SELECT
[wait_type],
[wait_time_ms] / 1000.0 AS [WaitS],
([wait_time_ms] - [signal_wait_time_ms]) / 1000.0 AS [ResourceS],
[signal_wait_time_ms] / 1000.0 AS [SignalS],
[waiting_tasks_count] AS [WaitCount],
100.0 * [wait_time_ms] / SUM ([wait_time_ms]) OVER() AS [Percentage],
ROW_NUMBER() OVER(ORDER BY [wait_time_ms] DESC) AS [RowNum]
FROM sys.dm_os_wait_stats
WHERE [wait_type] NOT IN (
N'BROKER_EVENTHANDLER', N'BROKER_RECEIVE_WAITFOR',
N'BROKER_TASK_STOP', N'BROKER_TO_FLUSH',
N'BROKER_TRANSMITTER', N'CHECKPOINT_QUEUE',
N'CHKPT', N'CLR_AUTO_EVENT',
N'CLR_MANUAL_EVENT', N'CLR_SEMAPHORE',
N'DBMIRROR_DBM_EVENT', N'DBMIRROR_EVENTS_QUEUE',
N'DBMIRROR_WORKER_QUEUE', N'DBMIRRORING_CMD',
N'DIRTY_PAGE_POLL', N'DISPATCHER_QUEUE_SEMAPHORE',
N'EXECSYNC', N'FSAGENT',
N'FT_IFTS_SCHEDULER_IDLE_WAIT', N'FT_IFTSHC_MUTEX',
N'HADR_CLUSAPI_CALL', N'HADR_FILESTREAM_IOMGR_IOCOMPLETION',
N'HADR_LOGCAPTURE_WAIT', N'HADR_NOTIFICATION_DEQUEUE',
N'HADR_TIMER_TASK', N'HADR_WORK_QUEUE',
N'KSOURCE_WAKEUP', N'LAZYWRITER_SLEEP',
N'LOGMGR_QUEUE', N'ONDEMAND_TASK_QUEUE',
N'PWAIT_ALL_COMPONENTS_INITIALIZED',
N'QDS_PERSIST_TASK_MAIN_LOOP_SLEEP',
N'QDS_CLEANUP_STALE_QUERIES_TASK_MAIN_LOOP_SLEEP',
N'REQUEST_FOR_DEADLOCK_SEARCH', N'RESOURCE_QUEUE',
N'SERVER_IDLE_CHECK', N'SLEEP_BPOOL_FLUSH',
N'SLEEP_DBSTARTUP', N'SLEEP_DCOMSTARTUP',
N'SLEEP_MASTERDBREADY', N'SLEEP_MASTERMDREADY',
N'SLEEP_MASTERUPGRADED', N'SLEEP_MSDBSTARTUP',
N'SLEEP_SYSTEMTASK', N'SLEEP_TASK',
N'SLEEP_TEMPDBSTARTUP', N'SNI_HTTP_ACCEPT',
N'SP_SERVER_DIAGNOSTICS_SLEEP', N'SQLTRACE_BUFFER_FLUSH',
N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
N'SQLTRACE_WAIT_ENTRIES', N'WAIT_FOR_RESULTS',
N'WAITFOR', N'WAITFOR_TASKSHUTDOWN',
N'WAIT_XTP_HOST_WAIT', N'WAIT_XTP_OFFLINE_CKPT_NEW_LOG',
N'WAIT_XTP_CKPT_CLOSE', N'XE_DISPATCHER_JOIN',
N'XE_DISPATCHER_WAIT', N'XE_TIMER_EVENT')
AND [waiting_tasks_count] > 0
)
SELECT
MAX ([W1].[wait_type]) AS [WaitType],
CAST (MAX ([W1].[WaitS]) AS DECIMAL (16,2)) AS [Wait_S],
CAST (MAX ([W1].[ResourceS]) AS DECIMAL (16,2)) AS [Resource_S],
CAST (MAX ([W1].[SignalS]) AS DECIMAL (16,2)) AS [Signal_S],
MAX ([W1].[WaitCount]) AS [WaitCount],
CAST (MAX ([W1].[Percentage]) AS DECIMAL (5,2)) AS [Percentage],
CAST ((MAX ([W1].[WaitS]) / MAX ([W1].[WaitCount])) AS DECIMAL (16,4)) AS [AvgWait_S],
CAST ((MAX ([W1].[ResourceS]) / MAX ([W1].[WaitCount])) AS DECIMAL (16,4)) AS [AvgRes_S],
CAST ((MAX ([W1].[SignalS]) / MAX ([W1].[WaitCount])) AS DECIMAL (16,4)) AS [AvgSig_S]
FROM [Waits] AS [W1]
INNER JOIN [Waits] AS [W2]
ON [W2].[RowNum] <= [W1].[RowNum]
GROUP BY [W1].[RowNum]
HAVING SUM ([W2].[Percentage]) - MAX ([W1].[Percentage]) < 95; -- percentage threshold
GO

目前CXPACKET,我的服务器等待时间为63%:

等待统计

我提到了多篇文章从专家的建议,并看着MAXDOP通过的建议微软 ; 但是,我不确定这是什么最佳值。

我在这里找到了关于同一主题的一个问题,但是如果我同意Kin的建议,那么MAXDOP应该是4。在同一问题中,如果我们选择Max Vernon,应该是3。

请提供您宝贵的建议。

版本:Microsoft SQL Server 2014(SP3)(KB4022619)-12.0.6024.0(X64)2018年9月7日01:37:51企业版:Windows NT 6.3上基于内核的许可(64位)(内部版本9600 :)(管理程序)

并行成本阈值设置为70。在对相同值(分别从默认值到25和50)进行测试后,CTfP已设置为70。当它的default(5)MAXDOP为0时,的等待时间接近70%CXPACKET

sp_blitzfirst在专家模式下执行了60秒,下面是发现和等待状态的输出:

sp_blitzfirst


我同意@JaredKarney在他的回答中的评论:您要解决/解决什么问题?您是否遇到不良表现?您为什么认为CXPACKET的高等待时间不好?您能否详细说明为什么您的情况与关于此问题的所有其他问题和答案不同?
约翰aka hot2use19年

@ hot2use是的,我遇到性能问题,试图查看所有可能降低性能的方面。我不是CXPACKET等待统计的专家,因此希望获得专家的一些指导。
Learning_DBAdmin

Answers:


13

虚假

这就是等待统计报告发臭的原因:它不会告诉您服务器已启动多长时间。

我可以在您的CPU时间截图中看到它:55天!

好吧,让我们做一些数学运算。

数学

每天有86,400秒。

SELECT (86400 * 55) seconds_in_55_days

答案在那里? 4,752,000

您总共452,488有CXPACKET秒。

SELECT 4752000 / 452488 AS oh_yeah_that_axis

这给了您... 10(如果您进行实际的数学计算,则接近9.5)。

因此,尽管CXPACKET可能占您服务器等待的62%,但它仅发生约10%的时间。

不要管它

您已经对设置进行了正确的调整,如果您想以有意义的方式更改数字,该是进行实际查询和索引调整的时候了。

其他注意事项

CXPACKET可能是由倾斜的并行性引起的:

在较新的版本上,它可能会以CXCONSUMER的形式出现:

缺少第三方监视工具,可能值得您自己捕获等待状态:


10

等待统计只是数字。如果您的服务器什么都没做,那么您可能会出现某种等待。同样,根据定义,必须有一个等待百分比最高的等待。没有某种标准化就没有任何意义。如果我正确地读取任务管理器的输出,则您的服务器已启用55天。这意味着您总共只有每秒452000 /(55 * 86400)= 0.095等待秒CXPACKET。此外,由于您使用的是SQL Server 2014,因此您的CXPACKET等待包括良性并行等待和可行的等待。有关更多详细信息,请参见使并行等待可操作MAXDOP根据您在此处提出的结论,我不会得出错误的结论。

我将首先测量吞吐量。这里真的有问题吗?我们无法告诉您该怎么做,因为这取决于您的工作量。对于OLTP系统,您可能每秒测量事务。对于ETL,您可以测量每秒加载的行,依此类推。

如果确实有问题,并且需要提高系统性能,那么在遇到该问题时,我会检查CPU。如果CPU太高,则可能需要调整查询,增加服务器资源或减少活动查询的总数。如果CPU太低,那么您可能再次需要调整查询,增加活动查询的总数,或者可能是某些等待类型负责。

如果您确实选择查看等待统计信息,则应该仅在遇到性能问题的期间查看它们。几乎在所有情况下,查看过去55天的全球等待统计数据都不可行。它给数据增加了不必要的噪音,使您的工作更加困难。

完成适当的调查后,更改可能MAXDOP会为您提供帮助。对于您大小的服务器,我会坚持使用MAXDOP1、2、4或8。我们无法告诉您哪种服务器最适合您的工作负载。您需要在更改之前和之后监视吞吐量MAXDOP以得出结论。


0
  1. 您的“开始” maxdop应该为4;每个numa节点的核心数量最少(最多8个)。您的公式不正确。

  2. 等待特定类型的百分比很高,这意味着什么。SQL中的所有内容都在等待,因此某些东西总是最高的。高cxpacket等待的唯一事情是,您正在进行的并行度很高。CPU总体上看起来并不高(至少对于所提供的快照而言),因此可能不是问题。

  3. 在尝试解决问题之前,先定义问题。您要解决什么问题?在这种情况下,您似乎已将问题定义为cxpacket等待的百分比很高,但这本身并不是问题。


虚拟NUMA可以很容易地在每个numa节点上拥有2个核心。为什么您声称每个numa节点中最少的4个核心?你能解释你的意思吗?
Max Vernon19年

-2

我认为最相关的问题是……您实际上遇到任何性能问题吗?如果答案是否定的,那么为什么在没有问题的情况下寻找问题?

就像其他答案所说的那样,一切都在等待,所有CX等待都表明是否有并行查询,我要提到的是,如果您对查询有疑问,那么应该看看您设置的并行成本阈值是多少正在并行执行的查询,即那些没有执行大量并行工作的小型查询,这可能会使它们运行得更好,而不是更好,并且由于所有较小的查询正在运行,因此本应并行执行的大型查询被延迟了不好。

如果不是这样,则您没有问题停止尝试创建一个。


请完整阅读问题,提供了并行处理的成本阈值。
Learning_DBAdmin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.