Algoritmo di impostazione MAXDOP per SQL Server


67

Quando si configura un nuovo SQL Server, utilizzo il seguente codice per determinare un buon punto di partenza per l' MAXDOPimpostazione:

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

Mi rendo conto che questo è un po 'soggettivo e può variare in base a molte cose; tuttavia sto tentando di creare un pezzo di codice generico da utilizzare come punto di partenza per un nuovo server.

Qualcuno ha qualche input su questo codice?


1
La mia raccomandazione per l'impostazione predefinita con 4 processori è 2. 0 imposta su illimitato. E mentre sei lì a impostare il MAXDOP, ti consiglio di considerare di adeguare la Soglia di costo per il parallelismo (aka, CTFP) a un valore compreso tra 40 e 75. {La mia impostazione iniziale preferita è 42 ... per motivi che molti fan di fantascienza avrebbero riconoscere}
yeOldeDataSmythe

42 è, dopo tutto, la risposta a tutto. Questo post ha 42 mila visualizzazioni, per esempio.
Max Vernon,

Risposte:


49

Il modo migliore per farlo è: utilizzare coreinfo (utility di sysinternals) come questo ti darà

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

Ora, in base alle informazioni di cui sopra, l'impostazione Ideal MaxDop dovrebbe essere calcolata come

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.

Quindi la risposta è: " dipende " dal footprint del processore e dalla configurazione NUMA e dalla tabella seguente riassumerà ciò che ho spiegato sopra:

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.

Modificato: di seguito è riportato uno script TSQL rapido e sporco per generare consigli per l'impostazione 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: Per i futuri visitatori, puoi guardare la funzione PowerShell test-dbamaxdop (insieme ad altre funzioni DBA estremamente utili (TUTTO GRATIS !!).


caso quando cpu_count> hyperthread_ratio poi 1 altro 0 finisce, sei sicuro che sia vero? perché nel caso di 8 processori logici, 8 processori fisici e 1 come hyperthread_ratio. dice ancora che l'hyperthread è abilitato, che trovo difficile da credere. E in quel caso, ottieni anche MAXDOP come 1, che non sembra vero.
UdIt Solanki,

@UdItSolanki Il modo corretto è utilizzare coreinfo per determinare se HT è abilitato o meno. Non esiste un modo definitivo per sapere se HT è abilitato utilizzando TSQL. Hai provato test-dbamaxdopcome indicato nella mia risposta?
Kin Shah,

17

Quando si imposta MAXDOP, in genere si desidera limitarlo al numero di core in un nodo NUMA. In questo modo le pianificazioni non stanno tentando di accedere alla memoria attraverso i nodi numa.


13

Guardando un post del team MSDN , ho trovato un modo per ottenere in modo affidabile il conteggio dei core fisici da una macchina e usarlo per determinare una buona impostazione MAXDOP.

Per "buono" intendo conservatore. Cioè, il mio requisito è utilizzare un massimo del 75% dei core in un nodo NUMA o un massimo complessivo di 8 core.

SQL Server 2016 (13.x) SP2 e versioni successive e tutte le versioni di SQL Server 2017 e versioni successive dettagli di superficie relativi al conteggio dei nuclei fisici per socket, al conteggio dei socket e al numero di nodi NUMA, consentendo un modo ordinato per determinare la baseline Impostazione MAXDOP per una nuova installazione di SQL Server.

Per le versioni sopra menzionate, questo codice raccomanderà un'impostazione MAXDOP conservativa del 75% del numero di core fisici in un nodo 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;';

Per le versioni di SQL Server precedenti a SQL Server 2017 o SQL Server 2016 SP2, non è possibile ottenere il core-count-per-numa-node da sys.dm_os_sys_info. Invece, possiamo usare PowerShell per determinare il conteggio dei nuclei fisici:

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

Si può anche usare PowerShell per determinare il numero di core logici, che sarebbe probabilmente il doppio del numero di core fisici se HyperThreading è attivato:

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

Il 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));

Ho eseguito lo script e mi ha consigliato MAXDOP = 0. difficile da credere per 4 nodi NUMA, HT enbaled, processori logici = 20 per 4 core. Qualche idea sul perché?
BeginnerDBA

@BeginnerDBA - quale versione di SQL Server stai usando?
Max Vernon,

il suo SQL Server 2012 e simili per il caso in cui ho provato anche su SQL2014
BeginnerDBA

SQL Server è in esecuzione in una macchina virtuale? Sembra che il numero di core per nodo numa sia 1 - forse la VM è configurata in modo strano? È possibile aggiungere questo alla fine dello script per scopi di debug: SELECT [@CoreCount] = @CoreCount , [@NumaNodes] = @NumaNodes , [@MaxDOP] = @MaxDOP
Max Vernon,

Grazie. No, è un server fisico, fammi provare ad aggiungere anche questo
BeginnerDBA,

11

Come regola generale, utilizzare un DOP più alto per un sistema OLAP e un DOP più basso (o no) per un sistema OLTP. Molti sistemi si trovano nel mezzo, quindi trova un mezzo felice che consenta al carico di lavoro occasionale di grandi dimensioni di ottenere abbastanza CPU da completare rapidamente, senza strozzare i carichi di lavoro OLTP.

Inoltre, fai attenzione all'utilizzo della cpu_countcolonna per ottenere un conteggio dei core. Se l'hyperthreading è abilitato, questa colonna sembra riflettere il numero di processori logici esposti. In generale, non si desidera che il DOP sia superiore al numero di core fisici. Distribuire un pesante carico di lavoro parallelo su processori logici aumenterà semplicemente le spese generali senza alcun vantaggio reale.

C'è anche una hyperthread_ratiocolonna, ma non sono sicuro di cosa rappresenti. Anche la documentazione non è molto chiara. Il numero che vedo sul nostro sistema suggerisce che potrebbe essere il numero di core fisici nell'intero sistema o il numero di processori logici per chip. La documentazione afferma che dovrei vedere una figura completamente diversa.


1
Credo che hyperthread_ratiosia la quantità di core logici per processore. L'ho incontrato un po 'di tempo fa e se ricordo bene questa è la conclusione a cui sono arrivato. Forse @AaronBertrand ha maggiori informazioni a riguardo. Non prenderlo come un fatto difficile e veloce ancora prima della verifica.
Thomas Stringer,

@ThomasStringer la documentazione afferma che, ed eseguendolo su più macchine, ecco come appare. Tuttavia, è piuttosto difficile dire da quella colonna se l'hyperthreading è effettivamente abilitato o meno. Ad esempio, su uno dei miei server riporta 8: il server ha 2 CPU fisiche, con 4 core su ogni CPU, con hyperthreading abilitato. Su macchine senza hyperthreading riporta 4 nelle stesse circostanze, ma senza riavviare (e disattivare hyperthreading), non vedresti mai quel cambiamento!
Max Vernon,

7

Mi sono anche imbattuto nell'articolo http://support.microsoft.com/kb/2806535 e non riesco a trovare la correlazione con gli script sopra.

Inoltre mi chiedo, perché esiste una differenziazione per "@logicalCPUs> = 8 e @HTEnabled = 1 e @NoofNUMA = 1" e "@logicalCPUs> = 8 e @HTEnabled = 1 e @NoofNUMA> 1" come risultato diventa lo stesso.

Dopotutto ho finito per scrivere il mio pezzo di codice corrispondente all'articolo dall'alto, anche se anche lì avrei adorato una definizione e / o una differenziazione più precisa di "processori" "CPU" e "processori fisici".

Sentiti libero di provare.

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

Bel pezzo di codice. Non sono sicuro se ti rendi conto che la hyperthread_ratiocolonna in sys.dm_os_sys_infoè fuorviante ... sulla mia workstation, ad esempio, ho una singola CPU a 4 core con hyperthreading abilitato - Task Manager vede 8 CPU logiche e il tuo codice riporta il rapporto hyperthreading a essere 1.
Max Vernon,

In quanto FYI, il mio codice produce una raccomandazione di 6 per questa macchina, che lascerà disponibili 2 core anche nelle query parallele più stressanti.
Max Vernon,

Hyperthread_ratio è davvero un problema, anche se non può essere risolto meglio, almeno non per quanto ne sappia. Vedi questo Blog per ulteriori dettagli: sqlblog.com/blogs/kalen_delaney/archive/2007/12/08/… E riguardo al tuo secondo post - Sarei felice di sapere quale valore per "massimo grado di parallelismo" hai scelto per la tua macchina. MrGreen Anche io sono abbastanza nuovo in questo argomento - mi sono appena imbattuto in questo solo perché non lo sapevo prima e avevo bisogno di queste informazioni. Quindi quale sarebbe la tua conclusione, i 2 core sono ancora disponibili una cosa buona o cattiva?
Dennis Winter,

4

Questa versione offre un bel set di risultati singolo con l'impostazione MAXDOP esistente e dovrebbe reggere le versioni SQL 2008-2017 senza la necessità di utilizzare 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);

3

Bellissimo script, ma l'articolo di kb: http://support.microsoft.com/kb/2806535 non è completamente compatibile con il tuo codice. Cosa mi sto perdendo?

Server 1
HTEnabled: 1
hyperthreadingRatio: 12
CPU logiche: 24
CPU fisiche: 2
CPU logiche per numa: 12
NoOfNuma: 2
impostazione MAXDOP dovrebbe essere: 6

Server 2
HTEnabled: 2
hyperthreadingRatio: 16
CPU logiche: 64
CPU fisiche: 4
CPU logiche per numa: 16
NoOfNuma: 4
L'impostazione MaxDop dovrebbe essere: 4

Mi rendo conto che questi sono solo suggerimenti; ma qualcosa non mi sembra giusto che un server (n. 2) sopra con 4 processori invece di 2 e 8 core per CPU fisica anziché 6; consiglierei MAXDOP a 4, contro 6 per il server meno potente.

L'articolo di Kbb sopra suggerisce 8 il mio scenario sopra. "Per i server con NUMA configurato e hyperthreading abilitato, il valore MAXDOP non deve superare il numero di processori fisici per nodo NUMA."


Se imposti MAXDOP su un valore superiore al numero di core / nodo numa, finirai con le chiamate nella memoria remota che sono molte volte più lente della chiamata vicino alla memoria. Questo perché ogni nodo numa ha la propria memoria; se una query utilizza più thread di quelli presenti in una singola modalità numa, il carico della CPU verrà distribuito su più core e quindi su più nodi di memoria.
Max Vernon,

Consiglio di impostare MAXDOP su un'impostazione che abbia senso per il tuo server che esegue il tuo carico. Solo tu puoi determinare l'impostazione migliore per il tuo carico particolare; questo post è solo indicativo.
Max Vernon,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.