Algorithme de paramétrage MAXDOP pour SQL Server

67

Lors de la configuration d'un nouveau serveur SQL, j'utilise le code suivant pour déterminer un bon point de départ pour le MAXDOPparamètre:

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

Je réalise que ceci est un peu subjectif et peut varier en fonction de nombreux facteurs. Cependant, j'essaie de créer un code fourre-tout à utiliser comme point de départ pour un nouveau serveur.

Quelqu'un at-il une entrée sur ce code?

Max Vernon
la source
1
Ma recommandation pour la configuration par défaut avec 4 processeurs est de 2. 0 le définit comme illimité. Et pendant que vous configurez le MAXDOP, je vous recommanderais de régler le seuil de coût pour le parallélisme (CTFP) entre 40 et 75. {Mon réglage initial favori est 42 ... pour des raisons que de nombreux fans de Sci-Fi voudraient reconnaître}
yeOldeDataSmythe
42 est, après tout, la réponse à tout. Cet article a 42 000 vues, par exemple.
Max Vernon

Réponses:

49

La meilleure façon de le faire est de - utiliser coreinfo (utilitaire de sysinternals) car cela vous donnera

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

Maintenant, en fonction des informations ci-dessus, le paramètre Ideal MaxDop doit être calculé comme suit:

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.

Donc, la réponse est: " Cela dépend " de l'encombrement de votre processeur et de la configuration NUMA. Le tableau ci-dessous résumera ce que j'ai expliqué ci-dessus:

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.

Modifié: Voici un script TSQL rapide et sale pour générer le paramètre Recommandation pour MAXDOP.

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

EDIT: Pour les futurs visiteurs, vous pouvez regarder la fonction test-dbamaxdop powershell (ainsi que d’ autres fonctions DBA extrêmement utiles (TOUT GRATUIT !!).

Kin Shah
la source
cas où cpu_count> hyperthread_ratio alors 1 sinon 0 fin, êtes-vous sûr que cela est vrai? parce que dans le cas de 8 processeurs logiques, 8 processeurs physiques et 1 comme hyperthread_ratio. il dit toujours que l'hyperthread est activé, ce qui est difficile à croire. Et dans ce cas, vous obtenez également MAXDOP en tant que 1, ce qui ne semble pas non plus être vrai.
UdIt Solanki
@UdItSolanki La méthode correcte consiste à utiliser coreinfo pour déterminer si HT est activé ou non. Il n'existe aucun moyen définitif de savoir si HT est activé à l'aide de TSQL. Avez-vous essayé test-dbamaxdopcomme mentionné dans ma réponse?
Kin Shah
17

Lorsque vous définissez MAXDOP, vous souhaitez généralement le limiter au nombre de cœurs dans un nœud NUMA. De cette façon, les planifications n'essayent pas d'accéder à la mémoire sur les nœuds numa.

mrdenny
la source
13

En examinant un article de l'équipe MSDN , j'ai trouvé un moyen d'obtenir de manière fiable le nombre de cœurs physique à partir d'une machine et de l'utiliser pour déterminer un bon paramètre MAXDOP.

Par "bon", je veux dire conservateur. C'est-à-dire que mon exigence est d'utiliser au maximum 75% des cœurs d'un noeud NUMA, ou un maximum global de 8 cœurs.

SQL Server 2016 (13.x) SP2 et versions ultérieures, ainsi que toutes les versions de SQL Server 2017 et versions ultérieures, donnent des informations détaillées sur le nombre de cœurs physique par socket, le nombre de sockets et le nombre de nœuds NUMA, ce qui permet de déterminer avec précision la ligne de base. Paramètre MAXDOP pour une nouvelle installation SQL Server.

Pour les versions mentionnées ci-dessus, ce code recommandera un paramètre MAXDOP conservateur de 75% du nombre de cœurs physiques dans un nœud NUMA:

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

Pour les versions de SQL Server antérieures à SQL Server 2017 ou SQL Server 2016 SP2, vous ne pouvez pas obtenir le nombre de nœuds par nombre de nœuds sys.dm_os_sys_info. À la place, nous pouvons utiliser PowerShell pour déterminer le nombre de cœurs physiques:

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

Vous pouvez également utiliser PowerShell pour déterminer le nombre de cœurs logiques, ce qui correspondrait probablement au double du nombre de cœurs physiques si HyperThreading est activé:

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

Le 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
la source
J'ai couru le script et il m'a recommandé MAXDOP = 0. Difficile à croire pour 4 nœuds NUMA, HT imbriqué, processeurs logiques = 20 pour 4 cœurs. Une idée pourquoi?
DébutantDBA le
@BeginnerDBA - quelle version de SQL Server utilisez-vous?
Max Vernon le
son serveur SQL 2012 et similaire pour le cas où j'ai testé sur SQL2014 aussi
DébutantDBA
SQL Server s'exécute-t-il sur une machine virtuelle? Il semble que le nombre de noyaux par nœud soit égal à 1 - peut-être que la machine virtuelle est configurée étrangement? Vous pouvez ajouter ceci à la fin du script à des fins de débogage: SELECT [@CoreCount] = @CoreCount , [@NumaNodes] = @NumaNodes , [@MaxDOP] = @MaxDOP
Max Vernon le
Merci. Non, c'est un serveur physique, laissez-moi essayer d'ajouter cela aussi
DébutantDBA
11

En règle générale, utilisez une valeur DOP plus élevée pour un système OLAP et une valeur DOP inférieure (ou nulle) pour un système OLTP. De nombreux systèmes se situent quelque part entre les deux. Trouvez donc un moyen qui permet à une charge de travail occasionnellement volumineuse de disposer de suffisamment de temps CPU pour se terminer rapidement, sans étrangler vos charges de travail OLTP.

Veillez également à utiliser la cpu_countcolonne pour obtenir un nombre de cœurs. Si l'hyperthreading est activé, cette colonne semble refléter le nombre de processeurs logiques exposés. De manière générale, vous ne voulez pas que le DOP soit supérieur au nombre de cœurs physiques. Répartir une lourde charge de travail parallèle sur les processeurs logiques ne fera qu'accroître les frais généraux sans réel bénéfice.

Il y a aussi une hyperthread_ratiocolonne, mais je ne suis pas certaine de ce qu'elle représente. La documentation n'est pas très claire non plus. Le nombre que je vois sur notre système suggère qu'il pourrait s'agir soit du nombre de cœurs physiques dans l'ensemble du système, soit du nombre de processeurs logiques par puce. La documentation prétend que je devrais voir un chiffre complètement différent.

db2
la source
1
Je crois que hyperthread_ratioc’est la quantité de cœurs logiques par processeur. Je me suis heurté à cela il y a quelque temps et si je me souviens bien, c'est la conclusion à laquelle je suis arrivé. Peut-être que @AaronBertrand a plus d'informations à ce sujet. Ne le prenez pas comme un fait absolu avant la vérification.
Thomas Stringer
La documentation de @ThomasStringer l'indique, et en l'exécutant sur plusieurs machines, c'est ce à quoi elle ressemble. Cependant, il est assez difficile de dire à partir de cette colonne si l'hyperthreading est réellement activé ou non. Par exemple, sur l'un de mes serveurs, il indique 8 - le serveur dispose de 2 processeurs physiques, avec 4 cœurs sur chaque processeur, avec l'hyperthreading activé. Sur les machines sans hyperthreading, il signale 4 dans les mêmes circonstances, mais sans redémarrage (et désactivation de l'hyperthreading), vous ne verriez jamais ce changement!
Max Vernon
7

Je suis également tombé sur l'article http://support.microsoft.com/kb/2806535 et ne trouve pas la corrélation avec les scripts ci-dessus.

Aussi, je me demande pourquoi il existe une différenciation pour "@logicalCPUs> = 8 et @HTEnabled = 1 et @NoofNUMA = 1" et "@logicalCPUs> = 8 et @HTEnabled = 1 et @NoofNUMA> 1" comme résultat devient le même.

Après tout, j'ai fini par écrire mon propre morceau de code correspondant à l'article d'en haut, même si j'aurais aimé une définition et / ou une différenciation plus précise concernant les "processeurs" "CPU" et les "processeurs physiques".

N'hésitez pas à avoir votre tour avec elle.

/*************************************************************************
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
la source
Beau morceau de code. Je ne sais pas si vous réalisez que la hyperthread_ratiocolonne sys.dm_os_sys_infoest trompeuse ... sur mon poste de travail, par exemple, je dispose d'un seul processeur 4 cœurs avec l'hyperthreading activé - Task Manager voit 8 processeurs logiques, et votre code indique le rapport d'hyperthreading à être 1.
Max Vernon
En tant que FYI, mon code produit une recommandation de 6 pour cette machine, ce qui laissera 2 cœurs disponibles même dans les requêtes parallèles les plus stressantes.
Max Vernon
L'hyperthread_ratio est effectivement un problème, mais il ne peut pas être résolu mieux - du moins pas à ma connaissance. Voir ce blog pour plus de détails: sqlblog.com/blogs/kalen_delaney/archive/2007/12/08/… Et à propos de votre deuxième article - j'aimerais bien savoir quelle valeur choisir pour "le degré de parallélisme maximum" pour votre machine. :-D Aussi, je suis assez nouveau dans ce sujet - je suis tombé dessus juste parce que je ne le savais pas avant et j'avais besoin de cette information. Ainsi quelle serait votre conclusion, est-ce que les 2 noyaux encore disponibles sont une bonne ou une mauvaise chose?
Dennis Winter
4

Cette version vous donne un ensemble de résultats unique avec le paramètre MAXDOP existant et devrait tenir sur les versions SQL 2008-2017 sans qu'il soit nécessaire d'utiliser xp_cmdshell.

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
la source
3

Beau script, mais l'article de ko: http://support.microsoft.com/kb/2806535 ne fonctionne pas complètement avec votre code. Qu'est-ce que je rate?

Serveur 1
HTEnabled: 1
hyperthreadingRatio: 12
cpus logiques: 24
cpus physiques: 2
cpus logiques par numéro: 12
NoOfNuma: 2
Le paramétrage MaxDop doit être: 6

Serveur 2
HTEconnecté: 2
hyperthreadingRatio: 16
cpus logique: 64
cpus physique : 64 cpus
logique: numa: 16
NoOfNuma: 4
Le réglage MaxDop doit être: 4.

Je me rends compte que ce ne sont que des suggestions; mais quelque chose ne me semble pas correct qu'un serveur (n ° 2) ci-dessus avec 4 processeurs au lieu de 2 et 8 cœurs par CPU physique au lieu de 6; recommande le MAXDOP à 4, contre 6 pour le serveur moins puissant.

L'article de kbb ci-dessus suggère 8 mon scénario ci-dessus. "Pour les serveurs sur lesquels NUMA est configuré et où l'hyperthreading est activé, la valeur MAXDOP ne doit pas dépasser le nombre de processeurs physiques par nœud NUMA."

Bob McC
la source
Si vous définissez MAXDOP plus élevé que le nombre de nœuds cœurs / numa, vous vous retrouvez avec des appels dans une mémoire lointaine beaucoup plus lents que si vous appeliez près de la mémoire. C'est parce que chaque nœud numa a sa propre mémoire; avoir une requête utilise plus de threads que ce qui est présent dans un seul mode numa répartira la charge du processeur sur plusieurs cœurs, et donc plusieurs nœuds de mémoire.
Max Vernon
Je recommande de définir MAXDOP sur un paramètre qui convient à votre serveur exécutant votre charge. Vous seul pouvez déterminer le meilleur réglage pour votre charge particulière; cet article n'est qu'une ligne directrice.
Max Vernon
2

Lors de l'installation de SQL Server 2019 CTP 3.0, un nouvel onglet MaxDOP a été créé. La valeur réelle est prédéfinie (dans les versions précédentes, la valeur par défaut était 0).

Définition de MAXDOP lors de l'installation de SQL Server 2019

entrez la description de l'image ici

Source de l'image: https://www.brentozar.com/wp-content/uploads/2019/05/SQL_Server_2019_Setup.png

lad2025
la source
yah, j'adore les fonctionnalités en 2019. C'est un changement particulièrement agréable.
Max Vernon