MAXDOP-Einstellungsalgorithmus für SQL Server

67

Beim Einrichten eines neuen SQL Servers verwende ich den folgenden Code, um einen guten Ausgangspunkt für die MAXDOPEinstellung zu bestimmen :

/* 
   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

Mir ist klar, dass dies ein bisschen subjektiv ist und aufgrund vieler Dinge variieren kann. Ich versuche jedoch, einen vollständigen Code zu erstellen, der als Ausgangspunkt für einen neuen Server dient.

Hat jemand eine Eingabe zu diesem Code?

Max Vernon
quelle
1
Meine Empfehlung für den Standard mit 4 Prozessoren ist 2. 0 setzt es auf unbegrenzt. Und während Sie den MAXDOP einstellen, würde ich Ihnen empfehlen, den Kostengrenzwert für Parallelität (auch bekannt als CTFP) auf einen Wert zwischen 40 und 75 einzustellen Wiedererkennen}
yeOldeDataSmythe
42 ist schließlich die Antwort auf alles. Dieser Beitrag hat zum Beispiel 42 Tausend Aufrufe.
Max Vernon

Antworten:

49

Am besten verwenden Sie coreinfo (Dienstprogramm von 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

Basierend auf den obigen Informationen sollte nun die ideale MaxDop-Einstellung wie folgt berechnet werden

a.  It has 12 CPUs which are hyper threaded giving us 24 CPUs.
b.  It has 2 NUMA node [Node 0 and 1] each having 12 CPUs with Hyperthreading ON.
c.  Number of sockets are 2 [socket 0 and 1] which are housing 12 CPUs each.

Considering all above factors, the max degree of Parallelism should be set to 6 which is ideal value for server with above configuration.

Die Antwort lautet also - " es hängt von Ihrem Prozessor-Footprint ab" und die NUMA-Konfiguration und die folgende Tabelle fassen zusammen, was ich oben erklärt habe:

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 CPUs assigned to each 
                                 NUMA node with max value capped to 8
Hyper threading Enabled ===> Should not exceed the number of physical processors.

Bearbeitet: Nachfolgend finden Sie ein schnelles und unsauberes TSQL-Skript zum Generieren der Empfehlung für die MAXDOP-Einstellung

/*************************************************************************
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

BEARBEITEN: Für zukünftige Besucher können Sie sich die PowerShell-Funktion test-dbamaxdop (zusammen mit anderen äußerst hilfreichen DBA-Funktionen (ALLES KOSTENLOS !!) ansehen .

Kin Shah
quelle
Wenn cpu_count> hyperthread_ratio und dann 1 else 0 enden, sind Sie sicher, dass dies wahr ist? weil im Fall von 8 logischen Prozessoren, 8 physischen Prozessoren und 1 als Hyperthread-Verhältnis. Es heißt immer noch, dass Hyperthread aktiviert ist, was ich kaum glauben kann. Und in diesem Fall erhalten Sie auch MAXDOP als 1, was ebenfalls nicht richtig klingt.
UdIt Solanki
@UdItSolanki Die richtige Methode besteht darin, mithilfe von coreinfo zu ermitteln, ob HT aktiviert ist oder nicht. Es gibt keine endgültige Methode, um festzustellen, ob HT mithilfe von TSQL aktiviert ist. Haben Sie versucht, test-dbamaxdopwie in meiner Antwort erwähnt?
Kin Shah
17

Wenn Sie MAXDOP einstellen, möchten Sie es normalerweise auf die Anzahl der Kerne in einem NUMA-Knoten beschränken. Auf diese Weise versuchen Zeitpläne nicht, über numa-Knoten auf Speicher zuzugreifen.

mrdenny
quelle
13

In einem Beitrag des MSDN-Teams habe ich mir eine Möglichkeit ausgedacht, die Anzahl der physischen Kerne eines Computers zuverlässig zu ermitteln und daraus eine gute MAXDOP-Einstellung zu ermitteln.

Mit "gut" meine ich konservativ. Das heißt, meine Anforderung besteht darin, maximal 75% der Kerne in einem NUMA-Knoten oder insgesamt maximal 8 Kerne zu verwenden.

SQL Server 2016 (13.x) SP2 und höher sowie alle Versionen von SQL Server 2017 und höher enthalten Informationen zur Anzahl der physischen Kerne pro Socket, zur Anzahl der Sockets und zur Anzahl der NUMA-Knoten MAXDOP-Einstellung für eine neue SQL Server-Installation.

Für die oben genannten Versionen empfiehlt dieser Code eine konservative MAXDOP-Einstellung von 75% der Anzahl der physischen Kerne in einem NUMA-Knoten:

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;';

Für Versionen von SQL Server vor SQL Server 2017 oder SQL Server 2016 SP2 können Sie den Core-Count-Per-Numa-Knoten nicht von beziehen sys.dm_os_sys_info. Stattdessen können wir PowerShell verwenden, um die Anzahl der physischen Kerne zu bestimmen:

powershell -OutputFormat Text -NoLogo -Command "& {Get-WmiObject -namespace 
"root\CIMV2" -class Win32_Processor -Property NumberOfCores} | select NumberOfCores"

Sie können auch PowerShell verwenden, um die Anzahl der logischen Kerne zu bestimmen. Dies ist wahrscheinlich die doppelte Anzahl der physischen Kerne, wenn HyperThreading aktiviert ist:

powershell -OutputFormat Text -NoLogo -Command "& {Get-WmiObject -namespace 
"root\CIMV2" -class Win32_Processor -Property NumberOfCores} 
| select NumberOfLogicalProcessors"

Das 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));
Max Vernon
quelle
Ich habe das Skript ausgeführt und es hat mir MAXDOP = 0 empfohlen. Kaum zu glauben für 4 NUMA-Knoten, HT-fähige logische Prozessoren = 20 pro 4 Kerne. Irgendeine Idee warum?
BeginnerDBA
@BeginnerDBA - Welche Version von SQL Server verwenden Sie?
Max Vernon
Sein SQL Server 2012 und ähnliches für den Fall, als ich auch auf SQL2014 testete
BeginnerDBA
Läuft SQL Server in einer VM? Es sieht so aus, als ob die Anzahl der Kerne pro numa-Knoten 1 ist - ist die VM möglicherweise seltsam konfiguriert? Sie können dies zu Debug-Zwecken am Ende des Skripts anfügen: SELECT [@CoreCount] = @CoreCount , [@NumaNodes] = @NumaNodes , [@MaxDOP] = @MaxDOP
Max Vernon,
Vielen Dank. Nein, es ist ein physischer Server. Lassen Sie mich versuchen, das auch hinzuzufügen
BeginnerDBA
11

Verwenden Sie in der Regel einen höheren DOP für ein OLAP-System und einen niedrigeren (oder keinen) DOP für ein OLTP-System. Viele Systeme befinden sich irgendwo dazwischen. Suchen Sie sich also ein gutes Medium, mit dem bei gelegentlich hoher Auslastung schnell genug CPU zur Verfügung steht, ohne die OLTP-Auslastung zu beeinträchtigen.

Seien Sie auch vorsichtig, wenn Sie die cpu_countSpalte verwenden, um eine Kernzählung zu erhalten. Wenn Hyperthreading aktiviert ist, scheint diese Spalte die Anzahl der verfügbaren logischen Prozessoren wiederzugeben. Im Allgemeinen soll der DOP nicht höher sein als die Anzahl der physischen Kerne. Wenn Sie eine hohe parallele Auslastung auf mehrere logische Prozessoren verteilen, erhöht sich der Overhead, ohne dass ein wirklicher Nutzen entsteht.

Es gibt auch eine hyperthread_ratioKolumne, aber ich bin mir nicht sicher, was sie darstellt. Die Dokumentation ist auch nicht sehr klar. Die Zahl, die ich auf unserem System sehe, lässt vermuten, dass es sich entweder um die Anzahl der physischen Kerne im gesamten System oder um die Anzahl der logischen Prozessoren pro Chip handelt. Die Dokumentation besagt, dass ich eine völlig andere Figur sehen sollte.

db2
quelle
1
Ich glaube, das hyperthread_ratioist die Anzahl der logischen Kerne pro Prozessor. Ich bin vor einiger Zeit darauf gestoßen, und wenn ich mich richtig erinnere, bin ich zu diesem Schluss gekommen. Vielleicht hat @AaronBertrand mehr Infos dazu. Nehmen Sie das noch nicht als eine feste Tatsache, bevor Sie es bestätigen.
Thomas Stringer
@ThomasStringer In der Dokumentation heißt es, dass es so aussieht, wenn es auf mehreren Computern ausgeführt wird. Es ist jedoch ziemlich schwierig, anhand dieser Spalte festzustellen, ob Hyperthreading tatsächlich aktiviert ist oder nicht. Beispielsweise meldet es auf einem meiner Server 8 - der Server verfügt über 2 physische CPUs mit 4 Kernen auf jeder CPU, wobei Hyperthreading aktiviert ist. Auf Rechnern ohne Hyperthreading werden unter den gleichen Umständen 4 gemeldet, aber ohne Neustart (und ohne Deaktivierung des Hyperthreading) wird diese Änderung nie beobachtet!
Max Vernon
7

Ich bin auch über den Artikel http://support.microsoft.com/kb/2806535 gestolpert und kann die Korrelation zu den obigen Skripten nicht finden.

Ich frage mich auch, warum es als Ergebnis eine Differenzierung für "@logicalCPUs> = 8 und @HTEnabled = 1 und @NoofNUMA = 1" und "@logicalCPUs> = 8 und @HTEnabled = 1 und @NoofNUMA> 1" gibt wird das gleiche.

Schließlich habe ich meinen eigenen Code geschrieben, der zu dem Artikel von oben passt, obwohl ich selbst dort eine genauere Definition und / oder Unterscheidung von "Prozessoren", "CPU" und "physischen Prozessoren" gewünscht hätte.

Fühlen Sie sich frei, Ihren Dreh mit ihm zu haben.

/*************************************************************************
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)
Dennis Winter
quelle
Schönes Stück Code. Ich bin nicht sicher, ob Sie feststellen, dass die hyperthread_ratioSpalte in sys.dm_os_sys_infoirreführend ist. Auf meiner Workstation habe ich beispielsweise eine einzelne 4-Core-CPU mit aktiviertem Hyperthreading. Der Task-Manager erkennt 8 logische CPUs und Ihr Code gibt das Hyperthreading-Verhältnis an 1. sein
Max Vernon
Als FYI gibt mein Code eine Empfehlung von 6 für diesen Computer aus, sodass auch bei den stressigsten parallelen Abfragen 2 Kerne verfügbar bleiben.
Max Vernon
Das hyperthread_ratio ist in der Tat ein Problem, kann aber - zumindest meines Wissens - nicht besser gelöst werden. Weitere Informationen finden Sie in diesem Blog: sqlblog.com/blogs/kalen_delaney/archive/2007/12/08/… Und zu Ihrem zweiten Beitrag - ich wäre schön zu wissen, welchen Wert Sie für "max degree of parallism" gewählt haben für Ihre Maschine. :-D Auch ich bin ziemlich neu in diesem Thema - bin nur darüber gestolpert, nur weil ich es vorher nicht wusste und diese Information brauchte. Also, was wäre Ihre Schlussfolgerung, sind die 2 noch verfügbaren Kerne eine gute oder eine schlechte Sache?
Dennis Winter
4

Diese Version bietet eine schöne Einzelergebnismenge mit der vorhandenen MAXDOP-Einstellung und sollte die Versionen SQL 2008-2017 ohne die Verwendung von xp_cmdshell unterstützen.

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);
ShadowDancerLV
quelle
3

Nettes Skript, aber der KB-Artikel: http://support.microsoft.com/kb/2806535 fügt sich nicht vollständig in Ihren Code ein. Was vermisse ich?

Server 1
HTEnabled: 1
HyperthreadingRatio: 12
logischer Prozessor: 24
physischer Prozessor: 2
logischer Prozessor pro Nummer: 12
NoOfNuma: 2
MaxDop-Einstellung sollte sein: 6

Server 2
HTEnabled: 2
HyperthreadingRatio: 16
logischer Prozessor: 64
physischer Prozessor: 4
logischer Prozessor pro Nummer numa: 16
NoOfNuma: 4
MaxDop-Einstellung sollte sein: 4

Mir ist klar, dass dies nur Vorschläge sind. aber etwas scheint mir nicht richtig, dass ein Server (# 2) oben mit 4 Prozessoren anstelle von 2 und 8 Kernen pro physischer CPU anstelle von 6; Ich würde den MAXDOP bei 4 empfehlen, gegenüber 6 für den weniger leistungsfähigen Server.

Der obige kbb-Artikel schlägt mein obiges Szenario vor. "Für Server, auf denen NUMA konfiguriert und Hyperthreading aktiviert ist, sollte der MAXDOP-Wert die Anzahl der physischen Prozessoren pro NUMA-Knoten nicht überschreiten."

Bob McC
quelle
Wenn Sie MAXDOP höher als die Anzahl der Kerne / NUMA-Knoten einstellen, erhalten Sie Aufrufe in den fernen Speicher, die um ein Vielfaches langsamer sind als Aufrufe in der Nähe des Speichers. Dies liegt daran, dass jeder numa-Knoten seinen eigenen Speicher hat. Wenn eine Abfrage mehr Threads verwendet, als in einem einzelnen numa-Modus vorhanden sind, wird die CPU-Last auf mehrere Kerne und daher auf mehrere Speicherknoten verteilt.
Max Vernon
Ich empfehle, MAXDOP auf eine Einstellung festzulegen, die für Ihren Server, auf dem Ihre Last ausgeführt wird, sinnvoll ist. Nur Sie können die beste Einstellung für Ihre jeweilige Last bestimmen. Dieser Beitrag ist nur eine Richtlinie.
Max Vernon
2

Während der Installation von SQL Server 2019 CTP 3.0 gibt es eine neue Registerkarte MaxDOP. Der tatsächliche Wert ist vordefiniert (in früheren Versionen war der Standardwert 0).

Einstellen von MAXDOP während des Setups von SQL Server 2019

Bildbeschreibung hier eingeben

Bildquelle: https://www.brentozar.com/wp-content/uploads/2019/05/SQL_Server_2019_Setup.png

lad2025
quelle
Ja, ich liebe die Features im Jahr 2019. Das ist eine besonders schöne Abwechslung.
Max Vernon