SOS_SCHEDULER_YIELD, SQL Server’ın “Cooperative Scheduling” (işbirlikçi zamanlama) mimarisinin doğal bir sonucudur. Bu bekleme tipi, bir thread’in (iş parçacığı) CPU üzerindeki çalışma süresini doldurduğunda, diğer işlemlere sıra vermek amacıyla CPU’yu gönüllü olarak bırakmasıyla oluşur.
SQL Server’da her scheduler (genellikle fiziksel/mantıksal CPU başına bir tane) üzerinde işlemler belirli bir düzenle çalışır. Bir thread CPU’da çalışmaya başladığında ona bir Quantum süresi tanımlanır.SQL Server’da bir quantum tam olarak 4 milisaniyedir. Eğer bir işlem 4 ms boyunca hiçbir I/O veya kilit (lock) engeline takılmadan çalışmaya devam ederse, scheduler tarafından durdurulmaz; thread “Benim işim henüz bitmedi ama kurallar gereği sıramı devrediyorum” diyerek CPU’yu bırakır. CPU’yu bırakan bu thread, “Runnable” (çalışmaya hazır) kuyruğunun en arkasına geçer. İşte SOS_SCHEDULER_YIELD beklemesi, bu thread’in kuyruğun en arkasından tekrar CPU’ya çıkana kadar geçen süreyi temsil eder.
Bu bekleme tipinin görülmesi her zaman bir hata olduğu anlamına gelmez. Ancak değerler çok yüksekse şu sorunlara işaret eder:
- Aşırı CPU Tüketimi: Karmaşık hesaplamalar yapan veya çok büyük veri setlerini bellek üzerinde tarayan (In-memory scan) sorgular.
- CPU Darboğazı: Mevcut işlemci gücünün, gelen yükü karşılamaya yetmemesi.
- Kötü Sorgu Planları: Yanlış index kullanımı nedeniyle işlemcinin milyonlarca satırı gereksiz yere check etmesi.
- Spinlock Çatışmaları: Çok nadir de olsa CPU’nun iç döngülerde takılması.
Sadece CPU tüketen sorguları değil, bu beklemenin sistem genelindeki etkisini ölçmek için aşağıdaki DMV (Dynamic Management View) analizleri yapılmalıdır:
Eğer aşağıdaki sorguda runnable_tasks_count değeri sürekli 0’dan büyükse, CPU üzerinde ciddi bir kuyruk var demektir.
SELECT scheduler_id, cpu_id, status, runnable_tasks_count, current_workers_count
FROM sys.dm_os_schedulers
WHERE status = 'VISIBLE ONLINE';
En Çok CPU Tüketen Top 10 Sorgu
SELECT TOP 10
st.text AS QueryText,
qs.total_worker_time / 1000 AS TotalCPUMs,
qs.total_worker_time / qs.execution_count / 1000 AS AvgCPUMs,
qs.execution_count,
qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
ORDER BY qs.total_worker_time DESC;
SOS_SCHEDULER_YIELD değerlerini düşürmek için şu adımlar izlenmelidir:
- İstatistikleri Güncelleyin: SQL Server’ın yanlış plan seçmesini önlemek için UPDATE STATISTICS komutunu çalıştırın.
- Index Optimizasyonu: Eksik index’leri (Missing Index) tamamlayın ancak “Index Scan” yerine “Index Seek” yapıldığından emin olun.
- MAXDOP Ayarı: Eğer paralellikten kaynaklı bir şişme varsa, Max Degree of Parallelism ayarını işlemci mimarinize (NUMA node yapısına) göre optimize edin.
- Implicit Conversion Kontrolü: Veri tipi uyuşmazlıkları CPU’ya her satırda dönüştürme yükü bindirir; bunları düzeltin.
- Donanım Ölçekleme: Yazılımsal tüm iyileştirmelere rağmen bekleme devam ediyorsa, CPU sayısını artırmayı veya daha yüksek saat hızına (clock speed) sahip işlemcilere geçmeyi değerlendirin.
- Resource Governor: Kritik olmayan iş yüklerinin (örneğin raporlama) CPU kullanımını sınırlayarak ana sistemin nefes almasını sağlayın.
SOS_SCHEDULER_YIELD beklemesi her zaman bir “bekleme” (waiting) değildir, bazen işlemcinin çok verimli çalıştığının (hiç durmadan hesaplama yaptığının) bir yan etkisidir. Önemli olan bu sürenin kullanıcı tarafında bir gecikmeye (latency) yol açıp açmadığıdır.
Başka makalede görüşmek dileğiyle..
Başkaları ile alay etmeyin. Hucurat-11
