AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 232943
Accepted
Learning_DBAdmin
Learning_DBAdmin
Asked: 2019-03-25 03:59:32 +0800 CST2019-03-25 03:59:32 +0800 CST 2019-03-25 03:59:32 +0800 CST

SQL Server 2014 的 MAXDOP 设置

  • 772

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

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

中央处理器

下面是 DB 服务器任务管理器中的 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) Sep 7 2018 01:37:51 Enterprise Edition:Windows NT 6.3 (Build 9600:) 上基于内核的许可(64 位)(管理程序) )

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

我sp_blitzfirst在专家模式下执行了 60 秒,下面是结果和等待统计的输出:

sp_blitzfirst

sql-server sql-server-2014
  • 4 4 个回答
  • 2598 Views

4 个回答

  • Voted
  1. Best Answer
    Erik Darling
    2019-03-25T06:24:09+08:002019-03-25T06:24:09+08:00

    虚假

    这就是为什么等待统计报告很糟糕的原因:它没有告诉你服务器已经运行了多长时间。

    我可以在你的 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 可能来自倾斜的并行性:

    • 更多关于 CXPACKET 等待:倾斜的并行性

    在较新的版本上,它可能显示为 CXCONSUMER:

    • CXCONSUMER 是无害的吗?没那么快,老虎。

    如果没有第三方监控工具,可能值得自己捕获等待统计信息:

    • 捕获一段时间的等待统计信息
    • 如何使用 sp_BlitzFirst 捕获基线
    • 13
  2. Joe Obbish
    2019-03-25T06:26:26+08:002019-03-25T06:26:26+08:00

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

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

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

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

    一旦你完成了适当的调查,改变可能MAXDOP会对你有所帮助。对于您大小的服务器,我会坚持使用MAXDOP1、2、4 或 8。我们无法告诉您其中哪一个最适合您的工作负载。您需要在更改前后监控您的吞吐量MAXDOP以做出结论。

    • 10
  3. Jared Karney
    2019-03-26T03:24:04+08:002019-03-26T03:24:04+08:00
    1. 你的“开始” maxdop 应该是 4;每个 numa 节点的最小核心数最多 8 个。您的公式不正确。

    2. 特定类型的高百分比等待没有任何意义。SQL 中的一切都在等待,所以某些东西总是最高的。唯一的高 cxpacket 等待意味着你有很高的并行度。CPU 整体看起来并不高(至少对于提供的快照而言),所以可能不是问题。

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

    • 0
  4. TheDwindlingDba
    2019-03-31T12:42:00+08:002019-03-31T12:42:00+08:00

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

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

    如果没有那么,你没有问题停止尝试创建一个。

    • -2

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve