MSSQL Server’da Bekleme Tiplerini (Wait Types) İzleme ve Loglama Altyapısı Kurulumu

Bu makalede SQL Server’da bekleme tiplerini (wait types) takip edip, belirli aralıklarla bunları bir tabloya loglayan ve sonra bu verileri analiz etmeni sağlayacak bir yapı kuracağız.

Yapılması gerekenler:

  • Belirli aralıklarla sistemdeki bekleme tiplerini toplamak
  • Bunları bir tabloya kaydetmek
  • Sonradan analiz edip en çok hangi beklemelerin yaşandığını görebilmek

Aşağıda kurulacak yapıda kullanacağımız genel ifadeleri görebilirsin.

  • sys.dm_os_wait_stats: SQL Server’daki bekleme istatistiklerini verir.
  • Bu DMV’den alınan verileri belli aralıklarla bir tabloya kaydedeceğiz.
  • Her çalıştırmada zaman damgası ile birlikte log tutulacak
  • İstersen bunu SQL Agent Job ile belirli aralıklarda çalıştırabilirsin (1 dk / 5 dk)

İlk olarak bir log tablosu oluşturulur. Aynı isimde log tablosu varsa silip tekrardan bir log tablosu oluşturur.

USE [master]; -- İstersen kendi veritabanında oluştur

IF OBJECT_ID('dbo.WaitStatsLog') IS NOT NULL DROP TABLE dbo.WaitStatsLog;

CREATE TABLE dbo.WaitStatsLog (
    log_time DATETIME NOT NULL DEFAULT GETDATE(),
    wait_type NVARCHAR(120),
    waiting_tasks_count BIGINT,
    wait_time_ms BIGINT,
    max_wait_time_ms BIGINT,
    signal_wait_time_ms BIGINT
);

Yukarıda oluşturulan tabloda sorgu performansını artırmak için tablo oluşturulduktan sonra aşağıdaki iki index oluşturulabilir.

CREATE NONCLUSTERED INDEX IX_WaitStatsLog_logtime
ON dbo.WaitStatsLog (log_time);

CREATE NONCLUSTERED INDEX IX_WaitStatsLog_waittype
ON dbo.WaitStatsLog (wait_type);

Bekleyen verileri log tablomuza aşağıdaki script ile yazabiliriz. Bu scripti bir job aracılığıyla belirli zaman belirlenerek çalıştırılabilir.

-- Wait statistics'i loga yaz
INSERT INTO dbo.WaitStatsLog (log_time, wait_type, waiting_tasks_count, wait_time_ms, max_wait_time_ms, signal_wait_time_ms)
SELECT 
    GETDATE(),
    wait_type,
    waiting_tasks_count,
    wait_time_ms,
    max_wait_time_ms,
    signal_wait_time_ms
FROM sys.dm_os_wait_stats
WHERE wait_type NOT IN (
    'CLR_SEMAPHORE', 'LAZYWRITER_SLEEP', 'RESOURCE_QUEUE',
    'SLEEP_TASK', 'SLEEP_SYSTEMTASK', 'SQLTRACE_BUFFER_FLUSH',
    'WAITFOR', 'LOGMGR_QUEUE', 'CHECKPOINT_QUEUE',
    'REQUEST_FOR_DEADLOCK_SEARCH', 'XE_TIMER_EVENT', 'XE_DISPATCHER_JOIN',
    'BROKER_TO_FLUSH', 'BROKER_TASK_STOP', 'CLR_MANUAL_EVENT',
    'CLR_AUTO_EVENT', 'DISPATCHER_QUEUE_SEMAPHORE', 'FT_IFTS_SCHEDULER_IDLE_WAIT',
    'BROKER_EVENTHANDLER', 'TRACEWRITE', 'XE_DISPATCHER_WAIT',
    'BROKER_RECEIVE_WAITFOR', 'REPUBLISH_QUEUE', 'PREEMPTIVE_OS_GETPROCADDRESS',
    'PREEMPTIVE_OS_AUTHENTICATIONOPS'
);
DELETE FROM dbo.WaitStatsLog
WHERE log_time < DATEADD(DAY, -7, GETDATE());

Not: Önemsiz ve sistemsel bekleme tipleri NOT IN komutuyla dahil edilmedi.

Not: Delete komutuyla job her çalıştırıldıktan sonra 7 gün önceki verileri tablodan silmektedir.

  • wait_type: Beklemenin adı (örnek: PAGEIOLATCH_SH, SOS_SCHEDULER_YIELD). Hangi tür işlemin beklediğini gösterir.
  • waiting_tasks_count: Bu bekleme tipine giren toplam işlem sayısı
  • wait_time_ms: Bu bekleme tipi için toplam beklenen süre (milisaniye olarak).
  • max_wait_time_ms: Bu türdeki beklemelerden en uzun sürenin süresi (milisaniye cinsinden).
  • signal_wait_time_ms: İşlem beklemesini bitirmiş ama CPU’ya erişmek için beklemiş süre. (Yani sistemde CPU darboğazı var mı gösterir.)

Diyelim ki son 2 saatte en çok beklenen wait type’ları görmek istiyorsanız aşağıdaki sorgu kullanılır.

SELECT 
   wait_type,
   COUNT(*) AS entry_count, -- loglanan kayıt sayısı
   SUM(waiting_tasks_count) AS total_tasks, -- toplam bekleyen görev sayısı
   SUM(wait_time_ms) / 1000.0 AS total_wait_seconds,-- toplam bekleme süresi (saniye)
    AVG(wait_time_ms) / 1000.0 AS avg_wait_seconds -- ortalama bekleme süresi (saniye)
FROM dbo.WaitStatsLog
WHERE log_time >= DATEADD(HOUR, -2, GETDATE())
--AND wait_type = 'PAGEIOLATCH_SH'--Bekleme türüne göre ek filtreleme koyulabilir.
GROUP BY wait_type
ORDER BY total_wait_seconds DESC;
  • COUNT(*) → Bu wait_type kaç kez loglandı
  • SUM(waiting_tasks_count): Bu bekleme türüne giren toplam işlem sayısı
  • SUM(wait_time_ms) → Tüm kayıtlar için toplam bekleme süresi
  • AVG(wait_time_ms) → Ortalama bekleme süresi (performans analizi için çok önemli)

Belirli bir zaman dilimi arasındaki bekleme tiplerini görmek için aşağıdaki komut kullanılmaktadır.

SELECT [log_time]
      ,[wait_type]
      ,[waiting_tasks_count]
      ,[wait_time_ms]
      ,[max_wait_time_ms]
      ,[signal_wait_time_ms]
  FROM [master].[dbo].[WaitStatsLog] where log_time between '2025-04-20 20:08:50.993' and '2025-04-20 20:08:50.993'

Başka bir makalede görüşmek dileğiyle..

“Göklerde ve yerde olan her şey yalnız Allah’ındır; kuşkusuz hiçbir şeye ihtiyacı olmayan ve her türlü övgüye lâyık olan yalnız Allah’tır.”Lokman-26

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir