Algoritmo de configuración MAXDOP para SQL Server

67

Cuando configuro un nuevo SQL Server, utilizo el siguiente código para determinar un buen punto de partida para la MAXDOPconfiguración:

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

Me doy cuenta de que esto es un poco subjetivo y puede variar según muchas cosas; Sin embargo, estoy tratando de crear un fragmento de código apretado para usar como punto de partida para un nuevo servidor.

¿Alguien tiene alguna entrada en este código?

Max Vernon
fuente
1
Mi recomendación para el valor predeterminado con 4 procesadores es 2. 0 lo establece en ilimitado. Y mientras esté allí configurando el MAXDOP, le recomendaría que considere ajustar el Umbral de costo para paralelismo (también conocido como CTFP) a algo entre 40 y 75. {Mi configuración inicial favorita es 42 ... por razones que muchos fanáticos de la ciencia ficción harían reconocer}
yeOldeDataSmythe
42 es, después de todo, la respuesta a todo. Esta publicación tiene 42 mil visitas, por ejemplo.
Max Vernon

Respuestas:

49

La mejor manera de hacerlo es usar coreinfo (utilidad de sysinternals) ya que esto le 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

Ahora, según la información anterior, la configuración Ideal MaxDop debe calcularse 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.

Entonces la respuesta es: " depende " de la huella de su procesador y la configuración de NUMA y la tabla a continuación resumirán lo que expliqué anteriormente:

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: a continuación se muestra un script TSQL rápido y sucio para generar recomendaciones para la configuración 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

EDITAR: Para futuros visitantes, puede consultar la función test-dbamaxdop powershell (junto con otras funciones DBA extremadamente útiles (¡TODO GRATIS!).

Kin Shah
fuente
caso cuando cpu_count> hyperthread_ratio luego 1 else 0 end, ¿estás seguro de que esto es cierto? porque en el caso de 8 procesadores lógicos, 8 procesadores físicos y 1 como hyperthread_ratio. todavía dice que hyperthread está habilitado, lo cual me resulta difícil de creer. Y en ese caso, también obtienes MAXDOP como 1, que tampoco suena cierto.
UdIt Solanki,
@UdItSolanki La forma correcta es usar coreinfo para determinar si HT está habilitado o no. No hay una forma definitiva de saber si HT está habilitado usando TSQL. ¿Intentaste test-dbamaxdopcomo se menciona en mi respuesta?
Kin Shah
17

Al configurar MAXDOP, normalmente desea limitarlo a la cantidad de núcleos en un nodo NUMA. De esa manera, los horarios no intentan acceder a la memoria a través de los nodos numa.

mrdenny
fuente
13

Mirando una publicación del equipo de MSDN , he encontrado una forma de obtener de forma confiable el recuento de núcleos físicos de una máquina, y usarlo para determinar una buena configuración de MAXDOP.

Por "bueno", quiero decir conservador. Es decir, mi requisito es utilizar un máximo del 75% de los núcleos en un nodo NUMA, o un máximo total de 8 núcleos.

SQL Server 2016 (13.x) SP2 y superior, y todas las versiones de SQL Server 2017 y superior muestran detalles sobre el recuento de núcleos físicos por socket, el recuento de socket y la cantidad de nodos NUMA, lo que permite una forma ordenada de determinar la línea base Configuración de MAXDOP para una nueva instalación de SQL Server.

Para las versiones mencionadas anteriormente, este código recomendará una configuración conservadora de MAXDOP del 75% del número de núcleos físicos en 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;';

Para las versiones de SQL Server anteriores a SQL Server 2017 o SQL Server 2016 SP2, no puede obtener el núcleo-count-per-numa-node de sys.dm_os_sys_info. En cambio, podemos usar PowerShell para determinar el recuento de núcleos físicos:

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

También se puede usar PowerShell para determinar la cantidad de núcleos lógicos, que probablemente sea el doble de la cantidad de núcleos físicos si HyperThreading está activado:

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

El 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
fuente
Ejecuté el script y me recomendó MAXDOP = 0. difícil de creer para 4 nodos NUMA, procesadores lógicos HT enbalados, 20 por 4 núcleos. ¿Alguna idea de por qué?
BeginnerDBA
@BeginnerDBA: ¿qué versión de SQL Server está utilizando?
Max Vernon
su servidor SQL 2012 y similar para el caso cuando probé también en SQL2014
BeginnerDBA
¿SQL Server se ejecuta en una VM? Parece que el recuento de núcleos por nodo numa es 1, ¿tal vez la VM está configurada de forma extraña? Puede agregar esto al final del script para fines de depuración: SELECT [@CoreCount] = @CoreCount , [@NumaNodes] = @NumaNodes , [@MaxDOP] = @MaxDOP
Max Vernon,
Gracias. No, es un servidor físico, déjenme intentar agregar eso también
BeginnerDBA
11

Como regla general, use una DOP más alta para un sistema OLAP y una DOP más baja (o nula) para un sistema OLTP. Muchos sistemas están en algún punto intermedio, así que encuentre un medio feliz que permita que la carga de trabajo grande y ocasional obtenga suficiente CPU para completar rápidamente, sin estrangular sus cargas de trabajo OLTP.

Además, tenga cuidado al usar la cpu_countcolumna para obtener un recuento de núcleos. Si se habilita hyperthreading, esta columna parece reflejar el número de procesadores lógicos expuestos. En términos generales, no desea que el DOP sea mayor que la cantidad de núcleos físicos. Distribuir una gran carga de trabajo en paralelo a través de procesadores lógicos solo aumentará la sobrecarga sin ningún beneficio real.

También hay una hyperthread_ratiocolumna, pero no estoy seguro de lo que representa. La documentación tampoco es muy clara. El número que veo en nuestro sistema sugiere que podría ser la cantidad de núcleos físicos en todo el sistema o la cantidad de procesadores lógicos por chip. La documentación afirma que debería ver una figura completamente diferente.

db2
fuente
1
Creo que hyperthread_ratioes la cantidad de núcleos lógicos por procesador. Me encontré con eso hace un tiempo y si no recuerdo mal, esa es la conclusión a la que llegué. Quizás @AaronBertrand tiene más información sobre eso. No tome eso como un hecho duro y rápido aún antes de la verificación.
Thomas Stringer
@ThomasStringer la documentación indica que, y al ejecutarlo en múltiples máquinas, así es como se ve. Sin embargo, es bastante difícil saber desde esa columna si hyperthreading está realmente habilitado o no. Por ejemplo, en uno de mis servidores informa 8: el servidor tiene 2 CPU físicas, con 4 núcleos en cada CPU, con hyperthreading habilitado. En máquinas sin hyperthreading, informa 4 en las mismas circunstancias, pero sin reiniciar (y desactivar hyperthreading), ¡nunca vería ese cambio!
Max Vernon
7

También me he tropezado con el artículo http://support.microsoft.com/kb/2806535 y no puedo encontrar la correlación con los scripts anteriores.

También me pregunto, por qué existe una diferenciación para "@logicalCPUs> = 8 y @HTEnabled = 1 y @NoofNUMA = 1" y "@logicalCPUs> = 8 y @HTEnabled = 1 y @NoofNUMA> 1" como resultado se convierte en lo mismo.

Después de todo, terminé escribiendo mi propio código que coincidía con el artículo de arriba, aunque incluso allí me hubiera encantado una definición y / o diferenciación más precisa sobre "procesadores", "CPU" y "procesadores físicos".

Siéntase libre de tener su giro con él.

/*************************************************************************
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
fuente
Bonito pedazo de código. No estoy seguro de si se da cuenta de que la hyperthread_ratiocolumna sys.dm_os_sys_infoes engañosa ... en mi estación de trabajo, por ejemplo, tengo una sola CPU de 4 núcleos con hyperthreading habilitado: el Administrador de tareas ve 8 CPU lógicas y su código informa la relación de hyperthreading a ser 1.
Max Vernon
Como FYI, mi código produce una recomendación de 6 para esta máquina, lo que dejará 2 núcleos disponibles incluso bajo las consultas paralelas más estresantes.
Max Vernon
El hyperthread_ratio es realmente un problema, aunque no se puede resolver mejor, al menos no que yo sepa. Vea este blog para obtener más detalles: sqlblog.com/blogs/kalen_delaney/archive/2007/12/08/… Y sobre su segunda publicación, me gustaría saber qué valor para "grado máximo de paralismo" ha elegido para tu máquina :-D También soy bastante nuevo en este tema, me topé con esto solo porque no lo sabía antes y necesitaba esta información. Entonces, ¿cuál sería su conclusión, si los 2 núcleos todavía están disponibles para algo bueno o malo?
Dennis Winter
4

Esta versión le ofrece un buen conjunto de resultados individuales con la configuración MAXDOP existente y debería mantenerse en las versiones SQL 2008-2017 sin la necesidad 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
fuente
3

Buen script, pero el artículo de kb: http://support.microsoft.com/kb/2806535 no coincide completamente con su código. ¿Qué me estoy perdiendo?

Servidor 1
HTEnabled: 1
hyperthreadingRatio: 12
cpus lógicos: 24
cpus físicos: 2
cpus lógicos por numa: 12
NoOfNuma: 2
La configuración MaxDop debe ser: 6

Server 2
HTEnabled: 2
hyperthreadingRatio: 16
cpus lógicos: 64
cpus físicos: 4
cpus lógicos por numa: 16
NoOfNuma: 4
La configuración de MaxDop debe ser: 4

Me doy cuenta de que estas son solo sugerencias; pero algo no me parece correcto que un servidor (# 2) anterior con 4 procesadores en lugar de 2 y 8 núcleos por CPU física en lugar de 6; recomendaría el MAXDOP en 4, frente a 6 para el servidor menos potente.

El artículo de kbb anterior sugiere 8 mi escenario anterior. "Para los servidores que tienen NUMA configurado y hyperthreading habilitado, el valor MAXDOP no debe exceder el número de procesadores físicos por nodo NUMA".

Bob McC
fuente
Si configura MAXDOP más alto que el número de núcleos / nodo numa, terminará con llamadas en la memoria lejana, que son muchas veces más lentas que las llamadas cercanas a la memoria. Esto se debe a que cada nodo numa tiene su propia memoria; hacer que una consulta use más hilos de los que están presentes en un solo modo numa distribuirá la carga de la CPU en múltiples núcleos y, por lo tanto, en múltiples nodos de memoria.
Max Vernon
Recomiendo configurar MAXDOP en una configuración que tenga sentido para que su servidor ejecute su carga. Solo usted puede determinar la mejor configuración para su carga particular; Esta publicación es solo una guía.
Max Vernon