Pengaturan MAXDOP untuk SQL Server 2014

8

Saya tahu pertanyaan ini telah ditanyakan beberapa kali dan juga memiliki jawaban untuk itu tetapi, saya masih memerlukan sedikit lebih banyak panduan tentang hal ini.

Di bawah ini adalah detail CPU saya dari SSMS:

CPU

Di bawah ini adalah tab CPU dari task manager dari DB Server:

Tab CPU

Saya telah menyimpan pengaturan MAXDOPpada 2 dengan mengikuti rumus di bawah ini:

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)

Saya masih melihat waktu tunggu yang tinggi terkait dengan CXPACKET. Saya menggunakan kueri di bawah ini untuk mendapatkan itu:

WITH [Waits] AS
(SELECT
[wait_type],
[wait_time_ms] / 1000.0 AS [WaitS],
([wait_time_ms] - [signal_wait_time_ms]) / 1000.0 AS [ResourceS],
[signal_wait_time_ms] / 1000.0 AS [SignalS],
[waiting_tasks_count] AS [WaitCount],
100.0 * [wait_time_ms] / SUM ([wait_time_ms]) OVER() AS [Percentage],
ROW_NUMBER() OVER(ORDER BY [wait_time_ms] DESC) AS [RowNum]
FROM sys.dm_os_wait_stats
WHERE [wait_type] NOT IN (
N'BROKER_EVENTHANDLER', N'BROKER_RECEIVE_WAITFOR',
N'BROKER_TASK_STOP', N'BROKER_TO_FLUSH',
N'BROKER_TRANSMITTER', N'CHECKPOINT_QUEUE',
N'CHKPT', N'CLR_AUTO_EVENT',
N'CLR_MANUAL_EVENT', N'CLR_SEMAPHORE',
N'DBMIRROR_DBM_EVENT', N'DBMIRROR_EVENTS_QUEUE',
N'DBMIRROR_WORKER_QUEUE', N'DBMIRRORING_CMD',
N'DIRTY_PAGE_POLL', N'DISPATCHER_QUEUE_SEMAPHORE',
N'EXECSYNC', N'FSAGENT',
N'FT_IFTS_SCHEDULER_IDLE_WAIT', N'FT_IFTSHC_MUTEX',
N'HADR_CLUSAPI_CALL', N'HADR_FILESTREAM_IOMGR_IOCOMPLETION',
N'HADR_LOGCAPTURE_WAIT', N'HADR_NOTIFICATION_DEQUEUE',
N'HADR_TIMER_TASK', N'HADR_WORK_QUEUE',
N'KSOURCE_WAKEUP', N'LAZYWRITER_SLEEP',
N'LOGMGR_QUEUE', N'ONDEMAND_TASK_QUEUE',
N'PWAIT_ALL_COMPONENTS_INITIALIZED',
N'QDS_PERSIST_TASK_MAIN_LOOP_SLEEP',
N'QDS_CLEANUP_STALE_QUERIES_TASK_MAIN_LOOP_SLEEP',
N'REQUEST_FOR_DEADLOCK_SEARCH', N'RESOURCE_QUEUE',
N'SERVER_IDLE_CHECK', N'SLEEP_BPOOL_FLUSH',
N'SLEEP_DBSTARTUP', N'SLEEP_DCOMSTARTUP',
N'SLEEP_MASTERDBREADY', N'SLEEP_MASTERMDREADY',
N'SLEEP_MASTERUPGRADED', N'SLEEP_MSDBSTARTUP',
N'SLEEP_SYSTEMTASK', N'SLEEP_TASK',
N'SLEEP_TEMPDBSTARTUP', N'SNI_HTTP_ACCEPT',
N'SP_SERVER_DIAGNOSTICS_SLEEP', N'SQLTRACE_BUFFER_FLUSH',
N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
N'SQLTRACE_WAIT_ENTRIES', N'WAIT_FOR_RESULTS',
N'WAITFOR', N'WAITFOR_TASKSHUTDOWN',
N'WAIT_XTP_HOST_WAIT', N'WAIT_XTP_OFFLINE_CKPT_NEW_LOG',
N'WAIT_XTP_CKPT_CLOSE', N'XE_DISPATCHER_JOIN',
N'XE_DISPATCHER_WAIT', N'XE_TIMER_EVENT')
AND [waiting_tasks_count] > 0
)
SELECT
MAX ([W1].[wait_type]) AS [WaitType],
CAST (MAX ([W1].[WaitS]) AS DECIMAL (16,2)) AS [Wait_S],
CAST (MAX ([W1].[ResourceS]) AS DECIMAL (16,2)) AS [Resource_S],
CAST (MAX ([W1].[SignalS]) AS DECIMAL (16,2)) AS [Signal_S],
MAX ([W1].[WaitCount]) AS [WaitCount],
CAST (MAX ([W1].[Percentage]) AS DECIMAL (5,2)) AS [Percentage],
CAST ((MAX ([W1].[WaitS]) / MAX ([W1].[WaitCount])) AS DECIMAL (16,4)) AS [AvgWait_S],
CAST ((MAX ([W1].[ResourceS]) / MAX ([W1].[WaitCount])) AS DECIMAL (16,4)) AS [AvgRes_S],
CAST ((MAX ([W1].[SignalS]) / MAX ([W1].[WaitCount])) AS DECIMAL (16,4)) AS [AvgSig_S]
FROM [Waits] AS [W1]
INNER JOIN [Waits] AS [W2]
ON [W2].[RowNum] <= [W1].[RowNum]
GROUP BY [W1].[RowNum]
HAVING SUM ([W2].[Percentage]) - MAX ([W1].[Percentage]) < 95; -- percentage threshold
GO

Saat ini CXPACKETserver menunggu 63% untuk server saya:

Tunggu Statistik

Saya merujuk beberapa artikel atas rekomendasi dari para ahli dan juga melihat MAXDOPsaran dari Microsoft ; Namun, saya tidak begitu yakin apa yang seharusnya menjadi nilai optimal untuk yang satu ini.

Saya menemukan satu pertanyaan tentang topik yang sama di sini, tetapi jika saya pergi dengan saran oleh Kin maka MAXDOPharus 4. Dalam pertanyaan yang sama, jika kita pergi dengan Max Vernon, itu harus 3.

Mohon berikan saran berharga Anda.

Versi: Microsoft SQL Server 2014 (SP3) (KB4022619) - 12.0.6024.0 (X64) Sep 7 2018 01:37:51 Edisi Perusahaan: Lisensi Berbasis Core (64-bit) pada Windows NT 6.3 (Build 9600:) (Hypervisor )

Ambang Batas Biaya untuk Paralelisme ditetapkan pada 70. CTfP telah ditetapkan ke 70 setelah menguji nilai yang sama mulai dari default hingga 25 dan 50 masing-masing. Ketika default (5) dan MAXDOP0, waktu tunggu mendekati 70% untuk CXPACKET.

Saya dieksekusi sp_blitzfirstselama 60 detik dalam mode pakar dan di bawah ini adalah output untuk temuan dan tunggu statistik:

sp_blitzfirst

Learning_DBAdmin
sumber
Saya setuju dengan komentar @JaredKarney dalam jawabannya: Apa yang Anda coba perbaiki / pecahkan? Apakah Anda mengalami kinerja yang buruk? Mengapa Anda percaya bahwa penantian CXPACKET tinggi itu buruk? Bisakah Anda menjelaskan mengapa situasi Anda berbeda dari semua pertanyaan dan jawaban lain tentang masalah ini?
John aka hot2use
@ hot2use Ya, saya mengalami masalah kinerja dan mencoba melihat semua aspek yang mungkin yang dapat menurunkan kinerja. Saya bukan ahli statistik tunggu CXPACKET dan karenanya ingin mendapatkan beberapa panduan dari para ahli.
Learning_DBAdmin

Jawaban:

13

Palsu

Inilah mengapa laporan statistik tunggu itu bau: Tidak memberi tahu Anda berapa lama server telah menyala.

Saya bisa melihatnya di tangkapan layar waktu CPU Anda: 55 hari!

Baiklah, jadi mari kita berhitung.

Matematika

Ada 86.400 detik dalam sehari.

SELECT (86400 * 55) seconds_in_55_days

Jawabannya di sana? 4,752,000

Anda memiliki total 452,488detik CXPACKET.

SELECT 4752000 / 452488 AS oh_yeah_that_axis

Yang memberi Anda ... 10 (lebih dekat ke 9,5 jika Anda melakukan matematika yang sebenarnya, di sini).

Jadi, sementara CXPACKET mungkin 62% dari server Anda menunggu, itu hanya terjadi sekitar 10% dari waktu.

Tinggalkan itu

Anda telah membuat penyesuaian yang tepat untuk pengaturan, saatnya untuk melakukan pencarian aktual dan pencarian indeks jika Anda ingin mengubah angka dengan cara yang bermakna.

Pertimbangan lainnya

CXPACKET dapat timbul dari paralelisme miring:

Pada versi yang lebih baru, ini mungkin muncul sebagai CXCONSUMER:

Jika tidak ada alat pemantauan pihak ketiga, mungkin ada baiknya Anda mengambil statistik tunggu sendiri:

Erik Darling
sumber
10

Tunggu statistik hanya angka. Jika server Anda melakukan sesuatu, Anda mungkin akan menunggu. Juga, menurut definisi harus ada satu menunggu yang akan memiliki persen tertinggi. Itu tidak berarti apa-apa tanpa semacam normalisasi. Server Anda telah aktif selama 55 hari jika saya membaca output dari task manager dengan benar. Itu berarti bahwa Anda hanya memiliki 452000 / (55 * 86400) = 0,095 detik menunggu CXPACKETper detik secara keseluruhan. Selain itu, karena Anda menggunakan SQL Server 2014, CXPACKETmenunggu Anda termasuk menunggu paralel jinak dan menunggu yang bisa ditindaklanjuti. Lihat Membuat paralelisme menunggu tindakan untuk rincian lebih lanjut. Saya tidak akan langsung mengambil kesimpulan yang MAXDOPditetapkan secara salah berdasarkan apa yang telah Anda sajikan di sini.

Pertama saya akan mengukur throughput. Apakah sebenarnya ada masalah di sini? Kami tidak dapat memberi tahu Anda cara melakukannya karena itu tergantung pada beban kerja Anda. Untuk sistem OLTP Anda dapat mengukur transaksi per detik. Untuk ETL, Anda bisa mengukur baris yang dimuat per detik, dan sebagainya.

Jika Anda memiliki masalah dan kinerja sistem perlu ditingkatkan, maka saya akan memeriksa CPU pada saat Anda mengalami masalah itu. Jika CPU terlalu tinggi maka Anda mungkin perlu menyetel kueri Anda, menambah sumber daya server, atau mengurangi jumlah total kueri aktif. Jika CPU terlalu rendah maka Anda mungkin perlu menyesuaikan lagi pertanyaan Anda, menambah jumlah total permintaan aktif, atau mungkin ada beberapa jenis menunggu yang bertanggung jawab.

Jika Anda memilih untuk melihat statistik tunggu, Anda harus melihatnya hanya selama periode di mana Anda mengalami masalah kinerja. Melihat statistik tunggu global selama 55 hari terakhir tidak dapat ditindaklanjuti di hampir semua kasus. Ini menambahkan suara yang tidak perlu ke data yang membuat pekerjaan Anda lebih sulit.

Setelah Anda menyelesaikan investigasi yang tepat, perubahan mungkin MAXDOPakan membantu Anda. Untuk server dengan ukuran Anda, saya akan tetap pada MAXDOP1, 2, 4, atau 8. Kami tidak dapat memberi tahu Anda yang mana dari yang terbaik untuk beban kerja Anda. Anda perlu memonitor throughput Anda sebelum dan sesudah berubah MAXDOPuntuk membuat kesimpulan.

Joe Obbish
sumber
0
  1. Maxdop 'awal' Anda harus 4; jumlah inti terkecil per simpul numa hingga 8. Rumus Anda salah.

  2. Persentase menunggu yang tinggi untuk jenis tertentu tidak berarti apa-apa. Semua yang ada di SQL menunggu, jadi selalu ada yang tertinggi. Satu-satunya hal yang menunggu cxpacket tinggi artinya adalah Anda memiliki persentase paralelisme yang tinggi. CPU tidak terlihat tinggi secara keseluruhan (setidaknya untuk snapshot yang disediakan), jadi mungkin bukan masalah.

  3. Sebelum mencoba menyelesaikan masalah, tentukan masalahnya. Masalah apa yang Anda sedang coba pecahkan? Dalam hal ini, tampaknya Anda telah mendefinisikan masalah sebagai persentase tinggi dari cxpacket menunggu, tetapi itu sendiri tidak menjadi masalah.

Jared Karney
sumber
NUMA virtual dapat dengan mudah memiliki 2 core per numa node. Mengapa Anda mengklaim 4 adalah jumlah terkecil dari simpul per numa node? Bisakah Anda menjelaskan maksud Anda?
Max Vernon
-2

Saya pikir pertanyaan yang paling relevan adalah ... apakah Anda benar-benar mengalami masalah kinerja? Jika jawabannya tidak, lalu mengapa Anda mencari masalah saat tidak ada?

Seperti jawaban lain katakan, semuanya menunggu, dan semua menunggu CX menunjukkan adalah jika Anda memiliki kueri yang paralel, sesuatu yang akan saya sebutkan adalah mungkin Anda harus melihat ambang batas biaya Anda untuk paralelisme ditetapkan pada JIKA Anda mengalami masalah dengan kueri yang berjalan paralel yaitu permintaan kecil yang tidak melakukan banyak pekerjaan paralel dan yang mungkin membuat mereka berjalan lebih buruk, tidak lebih baik, dan permintaan besar yang seharusnya paralel sedang tertunda karena semua yang lebih kecil yang menjalankan buruk

Jika tidak, Anda tidak perlu berhenti mencoba membuatnya.

TheDwindlingDba
sumber
Silakan baca pertanyaan sepenuhnya, ambang biaya untuk paralelisme disediakan.
Learning_DBAdmin