Algoritmo de configuração MAXDOP para SQL Server

67

Ao configurar um novo SQL Server, uso o código a seguir para determinar um bom ponto de partida para a MAXDOPconfiguração:

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

Sei que isso é um pouco subjetivo e pode variar com base em muitas coisas; no entanto, estou tentando criar um pedaço de código abrangente para usar como ponto de partida para um novo servidor.

Alguém tem alguma entrada nesse código?

Max Vernon
fonte
11
Minha recomendação para o padrão com 4 processadores é 2. 0 define como ilimitado. E enquanto você define o MAXDOP, recomendo que você ajuste o Limiar de custo para paralelismo (CTFP) para algo entre 40 e 75. {Minha configuração inicial favorita é 42 ... por motivos que muitos fãs de ficção científica reconhece}
yeOldeDataSmythe
42 é, afinal, a resposta para tudo. Este post tem 42 mil visualizações, por exemplo.
Max Vernon

Respostas:

49

A melhor maneira de fazer é - use coreinfo (utilitário pela sysinternals), pois isso lhe 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

Agora, com base nas informações acima, a configuração Ideal MaxDop deve ser calculada como

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.

Portanto, a resposta é - " depende " do espaço ocupado no processador e a configuração NUMA e a tabela abaixo resumirão o que expliquei acima:

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.

Editado: Abaixo está um script TSQL rápido e sujo para gerar a Recomendação para a configuração 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: Para futuros visitantes, você pode olhar para a função test-dbamaxdop powershell (junto com outras funções extremamente úteis do DBA (ALL FREE !!).

Kin Shah
fonte
caso, quando cpu_count> hyperthread_ratio e então 1 else 0 end, você tem certeza de que isso é verdade? porque no caso de 8 processadores lógicos, 8 processadores físicos e 1 como hyperthread_ratio. ainda diz que o hyperthread está ativado, o que acho difícil de acreditar. E nesse caso, você também recebe o MAXDOP como 1, o que também não parece verdadeiro.
UdIt Solanki
@UdItSolanki A maneira correta é usar o coreinfo para determinar se o HT está ativado ou não. Não há uma maneira definitiva de saber se o HT está ativado usando o TSQL. Você tentou test-dbamaxdopcomo mencionado na minha resposta?
Kin Shah
17

Ao configurar o MAXDOP, você normalmente deseja limitá-lo ao número de núcleos em um nó NUMA. Dessa forma, os agendamentos não estão tentando acessar a memória nos nós de uma.

Mrdenny
fonte
13

Olhando para uma postagem da equipe do MSDN , criei uma maneira de obter com segurança a contagem de núcleos físicos de uma máquina e usá-la para determinar uma boa configuração do MAXDOP.

Por "bom", quero dizer conservador. Ou seja, meu requisito é usar no máximo 75% dos núcleos em um nó NUMA ou no máximo 8 núcleos.

O SQL Server 2016 (13.x) SP2 e superior e todas as versões do SQL Server 2017 e acima da superfície detalham a contagem de núcleos físicos por soquete, a contagem de soquetes e o número de nós NUMA, permitindo uma maneira organizada de determinar a linha de base Configuração MAXDOP para uma nova instalação do SQL Server.

Para as versões mencionadas acima, esse código recomendará uma configuração conservadora MAXDOP de 75% do número de núcleos físicos em um nó 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;';

Para versões do SQL Server anteriores ao SQL Server 2017 ou SQL Server 2016 SP2, não é possível obter o nó da contagem de núcleos por numa sys.dm_os_sys_info. Em vez disso, podemos usar o PowerShell para determinar a contagem de núcleos físicos:

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

Também é possível usar o PowerShell para determinar o número de núcleos lógicos, o que provavelmente seria o dobro do número de núcleos físicos se o HyperThreading estiver ativado:

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

O 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
fonte
Eu executei o script e ele me recomendou MAXDOP = 0. difícil de acreditar para 4 nós NUMA, processadores lógicos com HT, = 20 por 4 núcleos. Alguma idéia do porquê?
BeginnerDBA
@BeginnerDBA - qual versão do SQL Server você está usando?
Max Vernon
seu SQL Server 2012 e semelhante para o caso quando eu testei no SQL2014 também
BeginnerDBA
O SQL Server está sendo executado em uma VM? Parece que a contagem de núcleos por nó é 1 - talvez a VM esteja configurada estranhamente? Você pode adicionar isso ao final do script para fins de depuração: SELECT [@CoreCount] = @CoreCount , [@NumaNodes] = @NumaNodes , [@MaxDOP] = @MaxDOP
Max Vernon
obrigado. Não, é um servidor físico, deixe-me tentar adicionar isso também
BeginnerDBA
11

Como regra geral, use DOP mais alto para um sistema OLAP e DOP mais baixo (ou nenhum) para um sistema OLTP. Muitos sistemas estão em algum lugar no meio; portanto, encontre um meio feliz que permita que uma carga de trabalho grande ocasional obtenha CPU suficiente para concluir rapidamente, sem estrangular suas cargas de trabalho OLTP.

Além disso, tenha cuidado ao usar a cpu_countcoluna para obter uma contagem principal. Se o hyperthreading estiver ativado, esta coluna parecerá refletir o número de processadores lógicos expostos. De um modo geral, você não deseja que o DOP seja maior que o número de núcleos físicos. A disseminação de uma carga de trabalho paralela pesada em processadores lógicos aumentará a sobrecarga sem nenhum benefício real.

Há também uma hyperthread_ratiocoluna, mas não tenho certeza do que ela representa. A documentação também não é muito clara. O número que vejo em nosso sistema sugere que pode ser o número de núcleos físicos em todo o sistema ou o número de processadores lógicos por chip. A documentação afirma que eu deveria estar vendo uma figura completamente diferente.

db2
fonte
11
Acredito que hyperthread_ratioseja a quantidade de núcleos lógicos por processador. Descobri isso há pouco tempo e, se bem me lembro, é a conclusão que cheguei. Talvez o @AaronBertrand tenha mais informações sobre isso. Não tome isso como um fato difícil e rápido ainda antes da verificação.
Thomas Stringer
@ThomasStringer a documentação afirma que, e de executá-lo em várias máquinas, é assim que parece. No entanto, é bastante difícil diferenciar dessa coluna se o hyperthreading está realmente ativado ou não. Por exemplo, em um dos meus servidores, ele reporta 8 - o servidor possui 2 CPUs físicas, com 4 núcleos em cada CPU, com o hyperthreading ativado. Em máquinas sem hyperthreading, ele informa 4 nas mesmas circunstâncias, mas sem reiniciar (e desativar o hyperthreading), você nunca veria essa alteração!
Max Vernon
7

Também tropecei no artigo http://support.microsoft.com/kb/2806535 e não consigo encontrar a correlação com os scripts acima.

Também estou me perguntando, por que existe uma diferenciação para "@logicalCPUs> = 8 e @HTEnabled = 1 e @NoofNUMA = 1" e "@logicalCPUs> = 8 e @HTEnabled = 1 e @NoofNUMA> 1" como resultado torna-se o mesmo.

Afinal, acabei escrevendo meu próprio pedaço de código correspondente ao artigo acima, embora mesmo lá eu tivesse adorado uma definição e / ou diferenciação mais precisa sobre "processadores", "CPU" e "processadores físicos".

Sinta-se livre para dar sua volta com ele.

/*************************************************************************
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
fonte
Bom pedaço de código. Não sei se você sabe que a hyperthread_ratiocoluna sys.dm_os_sys_infoé enganosa ... na minha estação de trabalho, por exemplo, tenho uma única CPU de 4 núcleos com o hyperthreading ativado - o Gerenciador de Tarefas vê 8 CPUs lógicas e seu código relata a taxa de hyperthreading para ser 1.
Max Vernon
Como FYI, meu código produz uma recomendação 6 para esta máquina, que deixará 2 núcleos disponíveis mesmo nas consultas paralelas mais estressantes.
Max Vernon
O hyperthread_ratio é realmente um problema, embora não possa ser resolvido melhor - pelo menos não que eu saiba. Consulte este blog para obter mais detalhes: sqlblog.com/blogs/kalen_delaney/archive/2007/12/08/… E sobre o seu segundo post - eu gostaria de saber qual o valor do "grau máximo de paralelismo" que você escolheu para a sua máquina. :-D Também sou bastante novo neste tópico - só me deparei com isso só porque não sabia antes e precisava dessas informações. Assim, qual seria sua conclusão: os 2 núcleos ainda estão disponíveis, uma coisa boa ou ruim?
Dennis Inverno
4

Esta versão fornece um bom conjunto de resultados com a configuração existente do MAXDOP e deve manter as versões do SQL 2008-2017 sem a necessidade de usar 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
fonte
3

Bom script, mas o artigo da kb: http://support.microsoft.com/kb/2806535 não combina completamente com o seu código. o que estou perdendo?

Servidor 1
HTEnabled: 1
hyperthreadingRatio: 12
cpus lógicos: 24
cpus físicos: 2
cpus lógicos por numa: 12
NoOfNuma: 2
A configuração MaxDop deve ser: 6

Servidor 2
HTEnabled: 2
hyperthreadingRatio: 16
cpus lógicos: 64
cpus físicos: 4
cpus lógicos por numa: 16
NoOfNuma: 4
A configuração MaxDop deve ser: 4

Eu percebo que estas são apenas sugestões; mas algo não me parece correto: um servidor (nº 2) acima com 4 processadores em vez de 2 e 8 núcleos por CPU física em vez de 6; recomendaria o MAXDOP em 4, contra 6 para o servidor menos poderoso.

O artigo da kbb acima sugere 8 meu cenário acima. "Para servidores com o NUMA configurado e o hyperthreading ativado, o valor MAXDOP não deve exceder o número de processadores físicos por nó do NUMA."

Bob McC
fonte
Se você definir o MAXDOP mais alto que o número de núcleos / nó numa, você terminará com as chamadas na memória remota muitas vezes mais lentas que as chamadas próximas à memória. Isso ocorre porque cada nó numa tem sua própria memória; fazer uma consulta usar mais threads do que o presente em um único modo, espalhará a carga da CPU por vários núcleos e, portanto, vários nós de memória.
Max Vernon
Eu recomendo definir MAXDOP para uma configuração que faça sentido para o seu servidor executando sua carga. Somente você pode determinar a melhor configuração para sua carga específica; este post é apenas uma diretriz.
Max Vernon