新しいSQL Serverをセットアップするときは、次のコードを使用してMAXDOP
設定の適切な開始点を決定します。
/*
This will recommend a MAXDOP setting appropriate for your machine's NUMA memory
configuration. You will need to evaluate this setting in a non-production
environment before moving it to production.
MAXDOP can be configured using:
EXEC sp_configure 'max degree of parallelism',X;
RECONFIGURE
If this instance is hosting a Sharepoint database, you MUST specify MAXDOP=1
(URL wrapped for readability)
http://blogs.msdn.com/b/rcormier/archive/2012/10/25/
you-shall-configure-your-maxdop-when-using-sharepoint-2013.aspx
Biztalk (all versions, including 2010):
MAXDOP = 1 is only required on the BizTalk Message Box
database server(s), and must not be changed; all other servers hosting other
BizTalk Server databases may return this value to 0 if set.
http://support.Microsoft.com/kb/899000
*/
DECLARE @CoreCount int;
DECLARE @NumaNodes int;
SET @CoreCount = (SELECT i.cpu_count from sys.dm_os_sys_info i);
SET @NumaNodes = (
SELECT MAX(c.memory_node_id) + 1
FROM sys.dm_os_memory_clerks c
WHERE memory_node_id < 64
);
IF @CoreCount > 4 /* If less than 5 cores, don't bother. */
BEGIN
DECLARE @MaxDOP int;
/* 3/4 of Total Cores in Machine */
SET @MaxDOP = @CoreCount * 0.75;
/* if @MaxDOP is greater than the per NUMA node
Core Count, set @MaxDOP = per NUMA node core count
*/
IF @MaxDOP > (@CoreCount / @NumaNodes)
SET @MaxDOP = (@CoreCount / @NumaNodes) * 0.75;
/*
Reduce @MaxDOP to an even number
*/
SET @MaxDOP = @MaxDOP - (@MaxDOP % 2);
/* Cap MAXDOP at 8, according to Microsoft */
IF @MaxDOP > 8 SET @MaxDOP = 8;
PRINT 'Suggested MAXDOP = ' + CAST(@MaxDOP as varchar(max));
END
ELSE
BEGIN
PRINT 'Suggested MAXDOP = 0 since you have less than 4 cores total.';
PRINT 'This is the default setting, you likely do not need to do';
PRINT 'anything.';
END
これは少し主観的であり、多くのものに基づいて変化する可能性があることを理解しています。しかし、私は新しいサーバーの出発点として使用するためのタイトなキャッチオールコードを作成しようとしています。
誰かがこのコードについて何か入力がありますか?
最良の方法は-coreinfo(sysinternalsによるユーティリティ)を使用することです。
a. Logical to Physical Processor Map
b. Logical Processor to Socket Map
c. Logical Processor to NUMA Node Map as below :
Logical to Physical Processor Map:
**---------------------- Physical Processor 0 (Hyperthreaded)
--**-------------------- Physical Processor 1 (Hyperthreaded)
----**------------------ Physical Processor 2 (Hyperthreaded)
------**---------------- Physical Processor 3 (Hyperthreaded)
--------**-------------- Physical Processor 4 (Hyperthreaded)
----------**------------ Physical Processor 5 (Hyperthreaded)
------------**---------- Physical Processor 6 (Hyperthreaded)
--------------**-------- Physical Processor 7 (Hyperthreaded)
----------------**------ Physical Processor 8 (Hyperthreaded)
------------------**---- Physical Processor 9 (Hyperthreaded)
--------------------**-- Physical Processor 10 (Hyperthreaded)
----------------------** Physical Processor 11 (Hyperthreaded)
Logical Processor to Socket Map:
************------------ Socket 0
------------************ Socket 1
Logical Processor to NUMA Node Map:
************------------ NUMA Node 0
------------************ NUMA Node 1
ここで、上記の情報に基づいて、Ideal MaxDop設定を次のように計算する必要があります
a. It has 12 CPU’s which are hyper threaded giving us 24 CPUs.
b. It has 2 NUMA node [Node 0 and 1] each having 12 CPU’s with Hyperthreading ON.
c. Number of sockets are 2 [socket 0 and 1] which are housing 12 CPU’s each.
Considering all above factors, the max degree of Parallelism should be set to 6 which is ideal value for server with above configuration.
したがって、答えは-「it依存」はプロセッサーのフットプリントとNUMA構成にあり、以下の表は上記で説明した内容をまとめたものです。
8 or less processors ===> 0 to N (where N= no. of processors)
More than 8 processors ===> 8
NUMA configured ===> MAXDOP should not exceed no of CPU’s assigned to each
NUMA node with max value capped to 8
Hyper threading Enabled ===> Should not exceed the number of physical processors.
編集済み:以下は、MAXDOP設定の推奨を生成するための迅速でダーティなTSQLスクリプトです
/*************************************************************************
Author : Kin Shah
Purpose : Recommend MaxDop settings for the server instance
Tested RDBMS : SQL Server 2008R2
**************************************************************************/
declare @hyperthreadingRatio bit
declare @logicalCPUs int
declare @HTEnabled int
declare @physicalCPU int
declare @SOCKET int
declare @logicalCPUPerNuma int
declare @NoOfNUMA 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
-- Report the recommendations ....
select
--- 8 or less processors and NO HT enabled
case
when @logicalCPUs < 8
and @HTEnabled = 0
then 'MAXDOP setting should be : ' + CAST(@logicalCPUs as varchar(3))
--- 8 or more processors and NO HT enabled
when @logicalCPUs >= 8
and @HTEnabled = 0
then 'MAXDOP setting should be : 8'
--- 8 or more processors and HT enabled and NO NUMA
when @logicalCPUs >= 8
and @HTEnabled = 1
and @NoofNUMA = 1
then 'MaxDop setting should be : ' + CAST(@logicalCPUPerNuma / @physicalCPU as varchar(3))
--- 8 or more processors and HT enabled and NUMA
when @logicalCPUs >= 8
and @HTEnabled = 1
and @NoofNUMA > 1
then 'MaxDop setting should be : ' + CAST(@logicalCPUPerNuma / @physicalCPU as varchar(3))
else ''
end as Recommendations
編集:将来の訪問者のために、あなたは test-dbamaxdop powershell関数を見ることができます ( DBA関数 (すべて無料!!)。
MAXDOPを設定するときは、通常、NUMAノードのコアの数に制限します。このようにして、スケジュールはnumaノード全体のメモリにアクセスしようとしません。
MSDNチームからの投稿 を見ると、マシンから物理コア数を確実に取得し、それを使用して適切なMAXDOP設定を決定する方法が考えられます。
「良い」とは、保守的な意味です。つまり、私の要件は、NUMAノードで最大75%のコア、または全体で最大8つのコアを使用することです。
SQL Server 2016(13.x)SP2以降、およびSQL Server 2017以降のすべてのバージョンでは、ソケットあたりの物理コア数、ソケット数、NUMAノードの数の詳細が表示されるため、ベースラインをきちんと決定できます新しいSQL ServerインストールのMAXDOP設定。
上記のバージョンの場合、このコードは、NUMAノードの物理コア数の75%という控えめなMAXDOP設定を推奨します。
DECLARE @socket_count int;
DECLARE @cores_per_socket int;
DECLARE @numa_node_count int;
DECLARE @memory_model nvarchar(120);
DECLARE @hyperthread_ratio int;
SELECT @socket_count = dosi.socket_count
, @cores_per_socket = dosi.cores_per_socket
, @numa_node_count = dosi.numa_node_count
, @memory_model = dosi.sql_memory_model_desc
, @hyperthread_ratio = dosi.hyperthread_ratio
FROM sys.dm_os_sys_info dosi;
SELECT [Socket Count] = @socket_count
, [Cores Per Socket] = @cores_per_socket
, [Number of NUMA nodes] = @numa_node_count
, [Hyperthreading Enabled] = CASE WHEN @hyperthread_ratio > @cores_per_socket THEN 1 ELSE 0 END
, [Lock Pages in Memory granted?] = CASE WHEN @memory_model = N'CONVENTIONAL' THEN 0 ELSE 1 END;
DECLARE @MAXDOP int = @cores_per_socket;
SET @MAXDOP = @MAXDOP * 0.75;
IF @MAXDOP >= 8 SET @MAXDOP = 8;
SELECT [Recommended MAXDOP setting] = @MAXDOP
, [Command] = 'EXEC sys.sp_configure N''max degree of parallelism'', ' + CONVERT(nvarchar(10), @MAXDOP) + ';RECONFIGURE;';
SQL Server 2017またはSQL Server 2016 SP2より前のバージョンのSQL Serverでは、sys.dm_os_sys_info
からcore-count-per-numa-nodeを取得できません。代わりに、PowerShellを使用して物理コア数を決定できます。
powershell -OutputFormat Text -NoLogo -Command "& {Get-WmiObject -namespace
"root\CIMV2" -class Win32_Processor -Property NumberOfCores} | select NumberOfCores"
PowerShellを使用して論理コアの数を決定することもできます。これは、ハイパースレッディングがオンの場合、物理コアの数の2倍になる可能性があります。
powershell -OutputFormat Text -NoLogo -Command "& {Get-WmiObject -namespace
"root\CIMV2" -class Win32_Processor -Property NumberOfCores}
| select NumberOfLogicalProcessors"
T-SQL:
/*
This will recommend a MAXDOP setting appropriate for your machine's NUMA memory
configuration. You will need to evaluate this setting in a non-production
environment before moving it to production.
MAXDOP can be configured using:
EXEC sp_configure 'max degree of parallelism',X;
RECONFIGURE
If this instance is hosting a Sharepoint database, you MUST specify MAXDOP=1
(URL wrapped for readability)
http://blogs.msdn.com/b/rcormier/archive/2012/10/25/
you-shall-configure-your-maxdop-when-using-sharepoint-2013.aspx
Biztalk (all versions, including 2010):
MAXDOP = 1 is only required on the BizTalk Message Box
database server(s), and must not be changed; all other servers hosting other
BizTalk Server databases may return this value to 0 if set.
http://support.Microsoft.com/kb/899000
*/
SET NOCOUNT ON;
DECLARE @CoreCount int;
SET @CoreCount = 0;
DECLARE @NumaNodes int;
/* see if xp_cmdshell is enabled, so we can try to use
PowerShell to determine the real core count
*/
DECLARE @T TABLE (
name varchar(255)
, minimum int
, maximum int
, config_value int
, run_value int
);
INSERT INTO @T
EXEC sp_configure 'xp_cmdshell';
DECLARE @cmdshellEnabled BIT;
SET @cmdshellEnabled = 0;
SELECT @cmdshellEnabled = 1
FROM @T
WHERE run_value = 1;
IF @cmdshellEnabled = 1
BEGIN
CREATE TABLE #cmdshell
(
txt VARCHAR(255)
);
INSERT INTO #cmdshell (txt)
EXEC xp_cmdshell 'powershell -OutputFormat Text -NoLogo -Command "& {Get-WmiObject -namespace "root\CIMV2" -class Win32_Processor -Property NumberOfCores} | select NumberOfCores"';
SELECT @CoreCount = CONVERT(INT, LTRIM(RTRIM(txt)))
FROM #cmdshell
WHERE ISNUMERIC(LTRIM(RTRIM(txt)))=1;
DROP TABLE #cmdshell;
END
IF @CoreCount = 0
BEGIN
/*
Could not use PowerShell to get the corecount, use SQL Server's
unreliable number. For machines with hyperthreading enabled
this number is (typically) twice the physical core count.
*/
SET @CoreCount = (SELECT i.cpu_count from sys.dm_os_sys_info i);
END
SET @NumaNodes = (
SELECT MAX(c.memory_node_id) + 1
FROM sys.dm_os_memory_clerks c
WHERE memory_node_id < 64
);
DECLARE @MaxDOP int;
/* 3/4 of Total Cores in Machine */
SET @MaxDOP = @CoreCount * 0.75;
/* if @MaxDOP is greater than the per NUMA node
Core Count, set @MaxDOP = per NUMA node core count
*/
IF @MaxDOP > (@CoreCount / @NumaNodes)
SET @MaxDOP = (@CoreCount / @NumaNodes) * 0.75;
/*
Reduce @MaxDOP to an even number
*/
SET @MaxDOP = @MaxDOP - (@MaxDOP % 2);
/* Cap MAXDOP at 8, according to Microsoft */
IF @MaxDOP > 8 SET @MaxDOP = 8;
PRINT 'Suggested MAXDOP = ' + CAST(@MaxDOP as varchar(max));
一般的なルールとして、OLAPシステムの場合は高いDOPを使用し、OLTPシステムの場合は低いDOPを使用します。多くのシステムはその中間にあり、したがって、OLTPワークロードを絞めずに、時折の大きなワークロードが十分なCPUを迅速に完了するのを可能にする幸せな媒体を見つけてください。
また、cpu_count
列を使用してコア数を取得するように注意してください。ハイパースレッディングが有効になっている場合、この列は公開されている論理プロセッサの数を反映しているようです。一般的に、DOPが物理コアの数を超えないようにする必要があります。重い並列ワークロードを論理プロセッサー全体に分散すると、オーバーヘッドが増えるだけで、実際にメリットはありません。
hyperthread_ratio
列もありますが、それが何を表しているのかはわかりません。ドキュメントもあまり明確ではありません。私のシステムに表示される数は、システム全体の物理コアの数か、チップあたりの論理プロセッサの数のいずれかである可能性を示唆しています。ドキュメントには、完全に別の図が表示されるはずだと記載されています。
また、この記事についてつまずきました http://support.Microsoft.com/kb/2806535 と上記のスクリプトとの相関関係を見つけることができません。
また、なぜ結果として「@logicalCPUs> = 8 and @HTEnabled = 1 and @NoofNUMA = 1」と「@logicalCPUs> = 8 and @HTEnabled = 1 and @NoofNUMA> 1」の違いがあるのかと思います。同じになります。
結局、上からの記事と一致する独自のコードを書いてしまいましたが、「プロセッサ」、「CPU」、「物理プロセッサ」についてのより正確な定義や区別が大好きだったでしょう。
自由に試してみてください。
/*************************************************************************
Author : Dennis Winter (Thought: Adapted from a script from "Kin Shah")
Purpose : Recommend MaxDop settings for the server instance
Tested RDBMS : SQL Server 2008R2
**************************************************************************/
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)
このバージョンは、既存のMAXDOP設定を使用して、Niceシングル結果セットを提供し、xp_cmdshellを使用する必要なく、SQL 2008-2017のバージョンを維持する必要があります。
select
[ServerName] = @@SERVERNAME
, [ComputerName] = SERVERPROPERTY('ComputerNamePhysicalNetBIOS')
, [LogicalCPUs]
, hyperthread_ratio
, [PhysicalCPU]
, [HTEnabled]
, LogicalCPUPerNuma
, [NoOfNUMA]
, [MaxDop_Recommended] = convert(int,case when [MaxDop_RAW] > 10 then 10 else [MaxDop_RAW] end)
, [MaxDop_Current] = sc.value
, [MaxDop_RAW]
, [Number of Cores]
from
(
select
[LogicalCPUs]
, hyperthread_ratio
, [PhysicalCPU]
, [HTEnabled]
, LogicalCPUPerNuma
, [NoOfNUMA]
, [Number of Cores]
, [MaxDop_RAW] =
case
when [NoOfNUMA] > 1 AND HTEnabled = 0 then logicalCPUPerNuma
when [NoOfNUMA] > 1 AND HTEnabled = 1 then convert(decimal(9,4),[NoOfNUMA]/ convert(decimal(9,4),Res_MAXDOP.PhysicalCPU) * convert(decimal(9,4),1))
when HTEnabled = 0 then Res_MAXDOP.LogicalCPUs
when HTEnabled = 1 then Res_MAXDOP.PhysicalCPU
end
from
(
select
[LogicalCPUs] = osi.cpu_count
, osi.hyperthread_ratio
, [PhysicalCPU] = osi.cpu_count/osi.hyperthread_ratio
, [HTEnabled] = case when osi.cpu_count > osi.hyperthread_ratio then 1 else 0 end
, LogicalCPUPerNuma
, [NoOfNUMA]
, [Number of Cores]
from
(
select
[NoOfNUMA] = count(res.parent_node_id)
,[Number of Cores] = res.LogicalCPUPerNuma/count(res.parent_node_id)
,res.LogicalCPUPerNuma
from
(
Select
s.parent_node_id
,LogicalCPUPerNuma = count(1)
from
sys.dm_os_schedulers s
where
s.parent_node_id < 64
and
s.status = 'VISIBLE ONLINE'
group by
s.parent_node_id
) Res
group by
res.LogicalCPUPerNuma
) Res_NUMA
cross apply sys.dm_os_sys_info osi
) Res_MAXDOP
)Res_Final
cross apply sys.sysconfigures sc
where sc.comment = 'maximum degree of parallelism'
option (recompile);
素晴らしいスクリプトですが、KBの記事 http://support.Microsoft.com/kb/2806535 は、コードを完全にうまく処理していません。何が欠けていますか?
サーバー1
HTEnabled:1
hyperthreadingRatio:12
論理CPU:24
物理CPU:2
ヌマあたりの論理CPU:12
NoOfNuma:2
MaxDop設定は6である必要があります
サーバー2
HTEnabled:2
hyperthreadingRatio:16
論理CPU:64
物理CPU:4
ヌマあたりの論理CPU:16
NoOfNuma:4
MaxDop設定は4である必要があります
これらは単なる提案にすぎません。しかし、上記のサーバー(#2)が2ではなく4プロセッサで、物理CPUごとに6コアではなく8コアを備えていることは、私には正しくないようです。 MAXDOPを4にすることをお勧めしますが、パフォーマンスの低いサーバーでは6にします。
上記のkbb記事は、上記の私のシナリオを示唆しています。 「NUMAが構成され、ハイパースレッディングが有効になっているサーバーの場合、MAXDOP値はNUMAノードあたりの物理プロセッサ数を超えてはなりません。」
SQL Server 2019 CTP 3.0のインストール中に、新しいタブMaxDOPがあります。実際の値は事前定義されています(以前のバージョンでは、デフォルトは0でした)。
SQL Server 2019セットアップ中のMAXDOPの設定
画像ソース: https://www.brentozar.com/wp-content/uploads/2019/05/SQL_Server_2019_Setup.png