Pemecahan masalah SOS_SCHEDULER_YIELD, tunggu

14

Menjalankan ERP perusahaan kami (Dynamics AX 2012), saya perhatikan lingkungan produksi kami tampak jauh lebih lambat daripada sistem pengembangan kami.

Setelah melakukan kegiatan yang sama di lingkungan pengembangan dan produksi saat menjalankan penelusuran, saya mengonfirmasi bahwa kueri SQL menjalankan sangat lambat pada lingkungan produksi kami dibandingkan dengan pengembangan (rata-rata 10-50x lebih lambat).

Pada awalnya saya mengaitkan ini dengan memuat, dan menjalankan kembali kegiatan yang sama pada lingkungan produksi selama jam-jam libur dan menemukan hasil yang sama dalam penelusuran.

Saya menghapus statistik menunggu saya di SQL Server kemudian membiarkan server berjalan di bawah beban produksi normal untuk sementara waktu, dan kemudian menjalankan kueri ini:

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'CLR_SEMAPHORE',    N'LAZYWRITER_SLEEP',
        N'RESOURCE_QUEUE',   N'SQLTRACE_BUFFER_FLUSH',
        N'SLEEP_TASK',       N'SLEEP_SYSTEMTASK',
        N'WAITFOR',          N'HADR_FILESTREAM_IOMGR_IOCOMPLETION',
        N'CHECKPOINT_QUEUE', N'REQUEST_FOR_DEADLOCK_SEARCH',
        N'XE_TIMER_EVENT',   N'XE_DISPATCHER_JOIN',
        N'LOGMGR_QUEUE',     N'FT_IFTS_SCHEDULER_IDLE_WAIT',
        N'BROKER_TASK_STOP', N'CLR_MANUAL_EVENT',
        N'CLR_AUTO_EVENT',   N'DISPATCHER_QUEUE_SEMAPHORE',
        N'TRACEWRITE',       N'XE_DISPATCHER_WAIT',
        N'BROKER_TO_FLUSH',  N'BROKER_EVENTHANDLER',
        N'FT_IFTSHC_MUTEX',  N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
        N'DIRTY_PAGE_POLL',  N'SP_SERVER_DIAGNOSTICS_SLEEP')
    )
SELECT
    [W1].[wait_type] AS [WaitType],
    CAST ([W1].[WaitS] AS DECIMAL(14, 2)) AS [Wait_S],
    CAST ([W1].[ResourceS] AS DECIMAL(14, 2)) AS [Resource_S],
    CAST ([W1].[SignalS] AS DECIMAL(14, 2)) AS [Signal_S],
    [W1].[WaitCount] AS [WaitCount],
    CAST ([W1].[Percentage] AS DECIMAL(4, 2)) AS [Percentage],
    CAST (([W1].[WaitS] / [W1].[WaitCount]) AS DECIMAL (14, 4)) AS [AvgWait_S],
    CAST (([W1].[ResourceS] / [W1].[WaitCount]) AS DECIMAL (14, 4)) AS [AvgRes_S],
    CAST (([W1].[SignalS] / [W1].[WaitCount]) AS DECIMAL (14, 4)) AS [AvgSig_S]
FROM [Waits] AS [W1] INNER JOIN [Waits] AS [W2] ON [W2].[RowNum] <= [W1].[RowNum]
GROUP BY [W1].[RowNum], [W1].[wait_type], [W1].[WaitS],
    [W1].[ResourceS], [W1].[SignalS], [W1].[WaitCount], [W1].[Percentage]
HAVING SUM ([W2].[Percentage]) - [W1].[Percentage] < 95; -- percentage threshold

Hasil saya adalah sebagai berikut:

WaitType               Wait_S  Resource_S  Signal_S  WaitCount  Percentage  AvgWait_S  AvgRes_S  AvgSig_S
SOS_SCHEDULER_YIELD   4162.52        3.64   4158.88    4450085       77.33     0.0009    0.0000    0.0009
ASYNC_NETWORK_IO       457.98      331.59    126.39     351113        8.51     0.0013    0.0009    0.0004
PAGELATCH_EX           252.94        5.14    247.80     796348        4.70     0.0003    0.0000    0.0003
WRITELOG               166.01       48.01    118.00     302209        3.08     0.0005    0.0002    0.0004
LCK_M_U                145.47      145.45      0.02        123        2.70     1.1827    1.1825    0.0002

Jadi sepertinya Tunggu terbesar adalah SOS_Scheduler_Yield sejauh ini, dan saya mencari-cari di sekitar dan menemukan itu biasanya berkaitan dengan CPU yang tidak dapat mengikuti.

Saya kemudian menjalankan kueri ini beberapa kali berturut-turut.

SELECT *
FROM sys.dm_os_schedulers
WHERE scheduler_id < 255

Saya tahu saya seharusnya mencari penjadwal dengan runnable_tasks_count non-nol atau pending_disk_io_count, tetapi pada dasarnya nol hampir sepanjang waktu.

Saya juga harus menyebutkan bahwa Max Degree of Parallelism ditetapkan ke 1, karena beban kerja Dynamics AX biasanya OLTP, dan mengubahnya 8 tidak membuat banyak perbedaan dalam statistik tunggu di atas, mereka menjadi hampir sama persis dengan yang sama. masalah kinerja.

Aku agak bingung ke mana harus pergi dari sini, pada dasarnya aku punya SQL Server yang tampaknya CPU terikat tetapi tidak menunggu di runnable_tasks atau IO.

Saya tahu bahwa subsistem IO dari SQL Server ini tidak terlalu baik, karena menjalankan SQLIO pada drive yang berisi database aktual dapat menyebabkan angka yang sangat rendah (pikirkan 10MB per detik untuk beberapa jenis baca / tulis), yang mengatakan, SQL sepertinya tidak menunggu karena jumlah memori di server yang menyimpan sebagian besar basis data.

Berikut ini beberapa informasi lingkungan untuk membantu:

Lingkungan produksi:

  • SQL Server
  • HP ProLian DL360p Gen8
  • Intel Xeon E5-2650 0 @ 2.00GHz x 2 dengan hyperthreading (32 core logis)
  • Memori 184GB
  • Windows Server 2012
  • 2 contoh dari SQL Server 2012 Standard (RTM, unpatched)
  • Raid 1 drive 279GB (15k) C: drive, berisi basis data dan sistem operasi
  • File Halaman dan TempDB pada drive yang berbeda dan terpisah (solid state)

DEV saya:

  • Hyper-V host SQL Server dan Dynamics AX 2012 AOS server
  • Core i7 3.4ghz dengan hyperthreading (8 core logis)
  • Memori 8GB
  • Windows Server 2008 R2
  • SSD untuk seluruh VM.

Saya akan menyambut setiap masukan tentang hal-hal lain yang harus dicari.

Nicholas Peterson
sumber

Jawaban:

16

Jadi saya menyelesaikan ini, ternyata fitur manajemen daya diaktifkan pada server SQL kami yang meningkatkan frekuensi CPU naik dan turun, tetapi tidak cukup cepat untuk mengikuti permintaan kecil dan memperkenalkan tunggu SOS_Scheduler_Yield. Setelah mengubahnya agar berjalan selalu dalam performa tinggi masalah hilang dan sekarang menunggu lebih normal (jenis barang LatchIO).

Nicholas Peterson
sumber