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:
Di bawah ini adalah tab CPU dari task manager dari DB Server:
Saya telah menyimpan pengaturan MAXDOP
pada 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 CXPACKET
server menunggu 63% untuk server saya:
Saya merujuk beberapa artikel atas rekomendasi dari para ahli dan juga melihat MAXDOP
saran 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 MAXDOP
harus 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 MAXDOP
0, waktu tunggu mendekati 70% untuk CXPACKET
.
Saya dieksekusi sp_blitzfirst
selama 60 detik dalam mode pakar dan di bawah ini adalah output untuk temuan dan tunggu statistik:
sumber
Jawaban:
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.
Jawabannya di sana?
4,752,000
Anda memiliki total
452,488
detik CXPACKET.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:
sumber
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
CXPACKET
per detik secara keseluruhan. Selain itu, karena Anda menggunakan SQL Server 2014,CXPACKET
menunggu 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 yangMAXDOP
ditetapkan 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
MAXDOP
akan membantu Anda. Untuk server dengan ukuran Anda, saya akan tetap padaMAXDOP
1, 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 berubahMAXDOP
untuk membuat kesimpulan.sumber
Maxdop 'awal' Anda harus 4; jumlah inti terkecil per simpul numa hingga 8. Rumus Anda salah.
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.
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.
sumber
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.
sumber