Algoritma pengaturan MAXDOP untuk SQL Server

67

Saat menyiapkan SQL Server baru, saya menggunakan kode berikut untuk menentukan titik awal yang baik untuk MAXDOPpengaturan:

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

Saya menyadari ini sedikit subjektif, dan dapat bervariasi berdasarkan banyak hal; namun saya mencoba membuat kode yang ketat untuk digunakan sebagai titik awal untuk server baru.

Adakah yang punya input pada kode ini?

Max Vernon
sumber
1
Rekomendasi saya untuk default dengan 4 prosesor adalah 2. 0 set ke tidak terbatas. Dan ketika Anda berada di sana mengatur MAXDOP, saya akan merekomendasikan Anda mempertimbangkan menyesuaikan Ambang Batas Biaya untuk Paralelisme (alias, CTFP) menjadi antara 40 dan 75. {Pengaturan awal favorit saya adalah 42 ... karena alasan banyak penggemar Sci-Fi akan kenali}
yeOldeDataSmythe
Lagi pula, 42 adalah jawaban untuk segalanya. Posting ini memiliki 42 ribu tampilan, misalnya.
Max Vernon

Jawaban:

49

Cara terbaik untuk melakukannya adalah - gunakan coreinfo (utilitas oleh sysinternals) karena ini akan memberi Anda

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

Sekarang, berdasarkan info di atas, pengaturan Ideal MaxDop harus dihitung sebagai

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.

Jadi jawabannya adalah - " itu tergantung " pada jejak prosesor Anda dan konfigurasi NUMA dan tabel di bawah ini akan merangkum apa yang saya jelaskan di atas:

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.

Diedit: Di bawah ini adalah skrip TSQL cepat dan kotor untuk menghasilkan Rekomendasi untuk pengaturan 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

SUNTING: Untuk pengunjung masa depan, Anda dapat melihat fungsi tes-dbamaxdop powershell (bersama dengan fungsi DBA lainnya yang sangat membantu (SEMUA GRATIS !!).

Kin Shah
sumber
kasus ketika cpu_count> hyperthread_ratio maka 1 lagi 0 akhir, apakah Anda yakin ini benar? karena dalam kasus 8 prosesor logis, 8 prosesor fisik dan 1 sebagai hyperthread_ratio. ia masih mengatakan hyperthread diaktifkan yang menurut saya sulit dipercaya. Dan dalam hal ini, Anda juga mendapatkan MAXDOP sebagai 1 yang juga tidak terdengar benar.
UdIt Solanki
@UdItSolanki Cara yang benar adalah dengan menggunakan coreinfo untuk menentukan apakah HT diaktifkan atau tidak. Tidak ada cara pasti untuk mengetahui apakah HT diaktifkan menggunakan TSQL. Apakah Anda mencoba test-dbamaxdopseperti yang disebutkan dalam jawaban saya?
Kin Shah
17

Saat mengatur MAXDOP, Anda biasanya ingin membatasinya ke jumlah inti dalam simpul NUMA. Dengan cara itu jadwal tidak mencoba mengakses memori melintasi numa node.

mrdenny
sumber
13

Melihat pos dari tim MSDN , saya telah menemukan cara untuk mendapatkan jumlah inti fisik dari mesin dengan andal, dan menggunakannya untuk menentukan pengaturan MAXDOP yang baik.

Dengan "baik", maksud saya konservatif. Artinya, persyaratan saya adalah untuk menggunakan maksimum 75% dari core dalam NUMA node, atau maksimum keseluruhan 8 core.

SQL Server 2016 (13.x) SP2 dan di atasnya, dan semua versi SQL Server 2017 dan detail permukaan di atas tentang jumlah inti fisik per soket, jumlah soket, dan jumlah node NUMA, memungkinkan cara yang rapi untuk menentukan garis dasar Pengaturan MAXDOP untuk instalasi SQL Server baru.

Untuk versi yang disebutkan di atas, kode ini akan merekomendasikan pengaturan MAXDOP konservatif 75% dari jumlah inti fisik dalam simpul 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;';

Untuk versi SQL Server sebelum SQL Server 2017 atau SQL Server 2016 SP2, Anda tidak bisa mendapatkan node-count-per-numa-node dari sys.dm_os_sys_info. Sebagai gantinya, kita dapat menggunakan PowerShell untuk menentukan jumlah inti fisik:

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

Satu juga dapat menggunakan PowerShell untuk menentukan jumlah core logis, yang kemungkinan akan menjadi dua kali lipat jumlah core fisik jika HyperThreading dihidupkan:

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

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
sumber
Saya menjalankan skrip dan merekomendasikan saya MAXDOP = 0. sulit dipercaya untuk 4 NUMA node, HT enbaled, prosesor logis = 20 per 4 core. Ada yang tahu kenapa?
BeginnerDBA
@BeginnerDBA - versi SQL Server apa yang Anda gunakan?
Max Vernon
SQL server 2012 dan serupa untuk kasus ini ketika saya diuji pada SQL2014 juga
BeginnerDBA
Apakah SQL Server berjalan di VM? Sepertinya jumlah inti per simpul numa adalah 1 - mungkin VM dikonfigurasi dengan aneh? Anda dapat menambahkan ini di akhir skrip untuk keperluan debugging: SELECT [@CoreCount] = @CoreCount , [@NumaNodes] = @NumaNodes , [@MaxDOP] = @MaxDOP
Max Vernon
Terima kasih. Tidak, ini server fisik, izinkan saya mencoba menambahkannya juga
BeginnerDBA
11

Sebagai aturan umum, gunakan DOP yang lebih tinggi untuk sistem OLAP, dan DOP yang lebih rendah (atau tidak ada) untuk sistem OLTP. Banyak sistem berada di antara keduanya, jadi temukan media bahagia yang memungkinkan beban kerja besar sesekali untuk mendapatkan CPU yang cukup untuk diselesaikan dengan cepat, tanpa mencekik beban kerja OLTP Anda.

Juga, berhati-hatilah dalam menggunakan cpu_countkolom untuk mendapatkan jumlah inti. Jika hyperthreading diaktifkan, kolom ini tampaknya mencerminkan jumlah prosesor logis yang terpapar. Secara umum, Anda tidak ingin DOP lebih tinggi dari jumlah inti fisik. Menyebarkan beban kerja paralel paralel di prosesor logis hanya akan meningkatkan overhead tanpa manfaat nyata.

Ada juga hyperthread_ratiokolom, tapi saya tidak yakin apa yang diwakilinya. Dokumentasinya juga tidak terlalu jelas. Angka yang saya lihat pada sistem kami menunjukkan bahwa itu bisa berupa jumlah core fisik di seluruh sistem, atau jumlah prosesor logis per chip. Dokumentasi mengklaim saya harus melihat sosok yang berbeda sama sekali.

db2
sumber
1
Saya percaya hyperthread_ratiojumlah inti logis per prosesor. Saya mengalami hal itu beberapa waktu lalu dan jika saya ingat dengan benar, itulah kesimpulan yang saya ambil. Mungkin @AaronBertrand memiliki info lebih lanjut tentang itu. Jangan menganggap itu sebagai fakta yang keras dan cepat sebelum verifikasi.
Thomas Stringer
@ThomasStringer dokumentasi menyatakan bahwa, dan dari menjalankannya di beberapa mesin, seperti itulah tampilannya. Namun, cukup sulit untuk mengetahui dari kolom itu apakah hipertensi benar-benar diaktifkan atau tidak. Sebagai contoh, pada salah satu server saya melaporkan 8 - server memiliki 2 CPU fisik, dengan 4 core pada setiap CPU, dengan hyperthreading diaktifkan. Pada mesin tanpa hipertransmisi melaporkan 4 dalam kondisi yang sama, tetapi tanpa me-reboot (dan mematikan hipertreading), Anda tidak akan pernah melihat perubahan itu!
Max Vernon
7

Saya juga menemukan artikel http://support.microsoft.com/kb/2806535 dan tidak dapat menemukan korelasi dengan skrip di atas.

Saya juga ingin tahu, mengapa ada diferensiasi untuk "@logicalCPUs> = 8 dan @HTEnabled = 1 dan @NoofNUMA = 1" dan "@logicalCPUs> = 8 dan @HTEnabled = 1 dan @NoofNUMA> 1" sebagai hasilnya menjadi sama.

Setelah semua saya akhirnya menulis sepotong kode saya sendiri yang cocok dengan artikel dari atas, meskipun bahkan di sana saya akan menyukai definisi dan / atau diferensiasi yang lebih tepat tentang "prosesor" "CPU" dan "prosesor fisik".

Merasa bebas untuk berputar dengan itu.

/*************************************************************************
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
sumber
Sepotong kode yang bagus. Saya tidak yakin apakah Anda menyadari bahwa hyperthread_ratiokolom sys.dm_os_sys_infoini menyesatkan ... di workstation saya, misalnya, saya memiliki CPU 4-core tunggal dengan diaktifkan HyperShreading - Task Manager melihat 8 CPU logis, dan kode Anda melaporkan rasio HyperShreading ke menjadi 1.
Max Vernon
Sebagai FYI, kode saya menghasilkan rekomendasi 6 untuk mesin ini, yang akan membuat 2 core tersedia bahkan di bawah permintaan paralel yang paling menegangkan.
Max Vernon
The hyperthread_ratio memang masalah, meskipun tidak dapat diselesaikan dengan lebih baik - setidaknya tidak sepengetahuan saya. Lihat Blog ini untuk beberapa perincian lebih lanjut: sqlblog.com/blogs/kalen_delaney/archive/2007/12/08/... Dan tentang postingan kedua Anda - Saya akan senang mengetahui, yang bernilai untuk "maks derajat parallisme" yang telah Anda pilih untuk mesin Anda. :-D Juga saya cukup baru dalam topik ini - hanya tersandung ini hanya karena saya tidak tahu sebelumnya dan membutuhkan informasi ini. Jadi apa kesimpulan Anda, apakah 2 core masih tersedia baik atau buruk?
Dennis Winter
4

Versi ini memberi Anda satu set hasil yang bagus dengan pengaturan MAXDOP yang ada dan harus tahan pada versi SQL 2008-2017 tanpa perlu menggunakan 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
sumber
3

Skrip yang bagus, tetapi artikel kb: http://support.microsoft.com/kb/2806535 tidak sepenuhnya cocok dengan kode Anda. Apa yang saya lewatkan?

Server 1
HTEnabled: 1
hyperthreadingRatio: 12
cpus logis: 24
cpus fisik: 2
cpus logis per numa: 12
NoOfNuma: 2
Pengaturan MaxDop harus: 6

Server 2
HTEnabled: 2
hyperthreadingRatio: 16
cpus logis: 64 cpus logis: 64
cpus
logis per 64 numa: 16
NoOfNuma: 4
Pengaturan MaxDop harus: 4

Saya menyadari ini hanya saran; tetapi sesuatu tampaknya tidak benar bagi saya bahwa server (# 2) di atas dengan 4 prosesor, bukan 2, dan 8 core per CPU fisik, bukan 6; akan merekomendasikan MAXDOP pada 4, dibandingkan 6 untuk server yang kurang kuat.

Artikel kbb di atas menyarankan 8 skenario saya di atas. "Untuk server yang mengonfigurasi NUMA dan mengaktifkan HyperShreading, nilai MAXDOP tidak boleh melebihi jumlah prosesor fisik per node NUMA."

Bob McC
sumber
Jika Anda menetapkan MAXDOP lebih tinggi dari jumlah node core / numa, Anda berakhir dengan panggilan ke memori jauh yang berkali-kali lebih lambat daripada memanggil memori dekat. Ini karena setiap node numa memiliki memori sendiri; memiliki kueri menggunakan lebih banyak utas daripada yang ada dalam mode numa tunggal akan menyebarkan beban CPU ke beberapa core, dan karenanya beberapa node memori.
Max Vernon
Saya merekomendasikan pengaturan MAXDOP ke pengaturan yang masuk akal untuk server Anda menjalankan beban Anda. Hanya Anda yang dapat menentukan pengaturan terbaik untuk muatan khusus Anda; posting ini hanya panduan.
Max Vernon