İÇİNDEKİLER
- •Yavaşlığın gerçek nedenini birlikte bulalım
- •Kısaca: Teşhis Akışı
- •1. Sorun Gerçekten Veritabanında mı?
- •2. Şu Anda Ne Oluyor?
- •3. SQL Server Neyi Bekliyor?
- •4. Kaynak Darboğazı: CPU, Disk mi, Bellek mi?
- •Disk gecikmesi
- •CPU
- •Bellek
- •5. Sorumlu Sorguyu Bulun
- •6. Ne Değişti?
- •Sık Yapılan Teşhis Hataları
- •Aryasoft ile SQL Server Performans İyileştirme
- •Sıkça Sorulan Sorular
- •Kaynaklar
- •Darboğazı tahminle değil, kanıtla bulun
SQL Server performans sorunlarını teşhis etmenin en hızlı yolu, tahmin yürütmek yerine sistemin neyi beklediğine bakmaktır. Teşhis dört soruyla ilerler: Sorun gerçekten veritabanında mı? SQL Server neyi bekliyor (CPU, disk, kilit, bellek)? Bu beklemeyi hangi sorgu veya oturum yaratıyor? Sorun yeni mi başladı, yoksa yavaş yavaş mı büyüdü? Bu yazı, bu dört soruyu sırasıyla yanıtlayan pratik bir teşhis akışı sunuyor.
Rehber; SQL Server’ı yöneten DBA’lar, yazılım ekipleri ve “sistem yavaş” şikâyetini çözmekle görevli BT yöneticileri için hazırlandı. Her adımda kullanılacak sorgular SQL Server 2025 üzerinde test edildi; SQL Server 2016 ve sonrasında da çalışır.
Yavaşlığın gerçek nedenini birlikte bulalım
Aryasoft'un kıdemli SQL Server uzmanları bekleme istatistiklerinden sorgu planlarına kadar sisteminizi inceler, darboğazı kanıtıyla gösterir ve kalıcı çözümü uygular.
Kısaca: Teşhis Akışı
| Adım | Soru | Bakılacak yer |
|---|---|---|
| 1 | Sorun veritabanında mı? | Uygulama, ağ ve sunucu metrikleri; şikâyetin kapsamı |
| 2 | Şu anda ne oluyor? | Çalışan istekler, blocking zincirleri |
| 3 | SQL Server neyi bekliyor? | Bekleme istatistikleri (wait stats) |
| 4 | Kaynak darboğazı hangisi? | CPU, disk gecikmesi, bellek |
| 5 | Hangi sorgu sorumlu? | Query Store, sorgu istatistikleri, yürütme planları |
| 6 | Ne değişti? | Yeni sürüm, plan değişikliği, veri hacmi, yapılandırma |
1. Sorun Gerçekten Veritabanında mı?
“Veritabanı yavaş” şikâyetlerinin önemli bir kısmının kaynağı veritabanı değildir: ağ gecikmesi, uygulama sunucusunun kaynak sıkıntısı veya uygulamanın satır satır veri çekmesi de aynı belirtiyi verir. İlk iş, şikâyetin kapsamını netleştirmektir:
- Tüm kullanıcılar mı, belirli bir ekran veya rapor mu yavaş?
- Yavaşlık sürekli mi, belirli saatlerde mi?
- Sorun ne zaman başladı ve o tarihte ne değişti?
Belirli bir ekran yavaşsa sorunu sorgu düzeyinde ararsınız; herkes aynı anda yavaşlıyorsa sorun büyük olasılıkla kaynak veya blocking kaynaklıdır.
2. Şu Anda Ne Oluyor?
Sorun devam ederken ilk bakılacak yer, çalışan isteklerdir. Aşağıdaki sorgu, her aktif oturumun ne kadar süredir çalıştığını, neyi beklediğini ve kimin tarafından bloklandığını gösterir:
SELECT r.session_id,
r.status,
r.blocking_session_id,
r.wait_type,
r.wait_time / 1000.0 AS wait_sec,
r.total_elapsed_time / 1000.0 AS elapsed_sec,
r.cpu_time / 1000.0 AS cpu_sec,
r.logical_reads,
DB_NAME(r.database_id) AS database_name,
SUBSTRING(t.text, r.statement_start_offset / 2 + 1,
(CASE r.statement_end_offset WHEN -1 THEN DATALENGTH(t.text)
ELSE r.statement_end_offset END - r.statement_start_offset) / 2 + 1) AS running_statement
FROM sys.dm_exec_requests AS r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS t
WHERE r.session_id <> @@SPID
AND r.session_id > 50
ORDER BY r.total_elapsed_time DESC;
blocking_session_id sıfırdan farklı olan satırlar, başka bir oturumu bekleyen oturumlardır. Zincirin başındaki oturum (kendisi kimseyi beklemeyen ama başkalarını bekleten), sorunun kaynağıdır.
Sahadan bir örnek: Büyük bir üretim firmasında ay sonu raporu tüm sistemi kilitlemişti. Zincirin başındaki oturum tespit edilip sonlandırıldı ve sistem 12 dakikada normale döndü. Ardından rapor iyileştirildi; çalışma süresi 4 saatten 19 dakikaya indi. Bu örnek iki şeyi gösteriyor: Acil müdahale ile kalıcı çözüm ayrı adımlardır ve ikisi de gereklidir.
Uyarı
Bir oturumu sonlandırmadan (KILL) önce ne yaptığına bakın. Saatlerdir çalışan büyük bir güncelleme işlemini sonlandırmak, işlemin geri alınmasını (rollback) başlatır ve bu süreç işlemin kendisinden uzun sürebilir. Karar mümkünse uygulama sahibiyle birlikte verilmelidir.
3. SQL Server Neyi Bekliyor?
SQL Server, bir sorgunun çalışamadığı her anı bir bekleme türü olarak kaydeder. Bekleme istatistikleri, teşhisin pusulasıdır: CPU mu, disk mi, kilit mi, bellek mi?
SELECT TOP (10)
wait_type,
wait_time_ms / 1000.0 AS wait_sec,
signal_wait_time_ms / 1000.0 AS signal_wait_sec,
waiting_tasks_count,
CAST(100.0 * wait_time_ms / SUM(wait_time_ms) OVER () AS decimal(5, 1)) AS pct
FROM sys.dm_os_wait_stats
WHERE wait_type NOT IN (N'SLEEP_TASK', N'LAZYWRITER_SLEEP', N'SQLTRACE_BUFFER_FLUSH',
N'XE_TIMER_EVENT', N'XE_DISPATCHER_WAIT', N'REQUEST_FOR_DEADLOCK_SEARCH',
N'LOGMGR_QUEUE', N'CHECKPOINT_QUEUE', N'BROKER_TO_FLUSH', N'BROKER_TASK_STOP',
N'DIRTY_PAGE_POLL', N'HADR_FILESTREAM_IOMGR_IOCOMPLETION', N'SP_SERVER_DIAGNOSTICS_SLEEP',
N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP', N'WAIT_XTP_OFFLINE_CKPT_NEW_LOG',
N'QDS_PERSIST_TASK_MAIN_LOOP_SLEEP', N'QDS_ASYNC_QUEUE', N'SOS_WORK_DISPATCHER',
N'FT_IFTS_SCHEDULER_IDLE_WAIT', N'XE_LIVE_TARGET_TVF', N'ONDEMAND_TASK_QUEUE',
N'DISPATCHER_QUEUE_SEMAPHORE', N'CLR_AUTO_EVENT', N'CLR_MANUAL_EVENT', N'WAITFOR',
N'PWAIT_EXTENSIBILITY_CLEANUP_TASK', N'PREEMPTIVE_XE_DISPATCHER', N'XE_DISPATCHER_JOIN',
N'HADR_WORK_QUEUE', N'HADR_TIMER_TASK', N'HADR_CLUSAPI_CALL', N'HADR_NOTIFICATION_DEQUEUE',
N'CHKPT', N'KSOURCE_WAKEUP', N'RESOURCE_QUEUE', N'SERVER_IDLE_CHECK')
AND wait_type NOT LIKE N'SLEEP[_]%'
AND wait_type NOT LIKE N'BROKER[_]%'
AND waiting_tasks_count > 0
ORDER BY wait_time_ms DESC;
Bu değerler sunucu son başlatıldığından beri birikir. Anlık bir sorunu incelerken iki ölçüm arasındaki farka bakmak daha doğru sonuç verir.
| Baskın bekleme | Ne anlama gelir? | İlk bakılacak yer |
|---|---|---|
| CXPACKET, CXCONSUMER | Paralel sorgular | MAXDOP ve cost threshold ayarları; büyük taramalar yapan sorgular |
| SOS_SCHEDULER_YIELD, yüksek signal wait | CPU baskısı | En çok CPU kullanan sorgular; plan değişiklikleri |
| PAGEIOLATCH_* | Veri sayfalarının diskten okunması | Eksik indeksler, büyük taramalar, bellek yetersizliği, disk gecikmesi |
| WRITELOG | Log diskine yazma | Log diskinin gecikmesi; çok sayıda küçük işlem |
| LCK_M_* | Kilit beklemeleri (blocking) | Uzun işlemler, eksik indeksler, işlem yönetimi |
| RESOURCE_SEMAPHORE | Sorguların bellek tahsisi beklemesi | Büyük bellek isteyen sorgular, hatalı tahminler |
| PAGELATCH_* (tempdb) | tempdb’de eşzamanlılık sıkışması | tempdb dosya sayısı ve yapısı |
| HADR_SYNC_COMMIT | Senkron replikaya commit bekleme | Ağ ve replika diskinin gecikmesi |
Bekleme türlerinin ayrıntılı yorumunu ve adım adım tanı akışını SQL Server Wait Stats Analizi yazımızda anlattık.
4. Kaynak Darboğazı: CPU, Disk mi, Bellek mi?
Disk gecikmesi
Disk kaynaklı yavaşlıklarda tahmin yerine dosya bazında gecikme ölçülmelidir. Aşağıdaki sorgu her veritabanı dosyası için ortalama okuma ve yazma gecikmesini milisaniye cinsinden verir:
SELECT DB_NAME(vfs.database_id) AS database_name,
mf.physical_name,
CAST(vfs.io_stall_read_ms / NULLIF(vfs.num_of_reads, 0) AS decimal(10, 1)) AS avg_read_ms,
CAST(vfs.io_stall_write_ms / NULLIF(vfs.num_of_writes, 0) AS decimal(10, 1)) AS avg_write_ms,
vfs.num_of_reads,
vfs.num_of_writes
FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS vfs
JOIN sys.master_files AS mf
ON mf.database_id = vfs.database_id AND mf.file_id = vfs.file_id
ORDER BY vfs.io_stall_read_ms + vfs.io_stall_write_ms DESC;
Paylaşımlı depolama ve sanallaştırma ortamlarında, sorunu sanallaştırma veya depolama ekibine bu tür ölçümlerle (IOPS, gecikme, kuyruk uzunluğu) götürmek çözüm sürecini belirgin şekilde hızlandırır. Disk yapılandırmasının temel kurallarını disk depolama rehberimizde bulabilirsiniz.
CPU
CPU baskısında önce SQL Server’ın gerçekten tüm çekirdekleri kullanıp kullanamadığını kontrol edin; lisans ve sanallaştırma kaynaklı çekirdek sınırları sık rastlanan bir nedendir. Ayrıntıları SQL Server kaç CPU kullanabilir yazımızda anlattık. Ardından en çok CPU kullanan sorgulara geçin (5. adım).
Bellek
PAGEIOLATCH beklemeleri ve sürekli diskten okuma, bellek yetersizliğine işaret edebilir. Ancak çoğu zaman asıl sorun belleğin kendisi değil, gereğinden fazla veri okuyan sorgulardır. Bellek eklemeden önce en çok okuma yapan sorgulara bakın.
5. Sorumlu Sorguyu Bulun
Query Store açıksa, bir sorgunun hangi tarihten itibaren yavaşladığını ve hangi yürütme planını kullandığını geriye dönük olarak görebilirsiniz. Query Store kapalıysa, plan önbelleğindeki istatistiklerle başlayın:
SELECT TOP (10)
qs.total_worker_time / 1000 AS total_cpu_ms,
qs.total_logical_reads,
qs.execution_count,
qs.total_worker_time / qs.execution_count / 1000 AS avg_cpu_ms,
SUBSTRING(t.text, qs.statement_start_offset / 2 + 1,
(CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(t.text)
ELSE qs.statement_end_offset END - qs.statement_start_offset) / 2 + 1) AS statement_text
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS t
ORDER BY qs.total_worker_time DESC;
Sıralamayı total_logical_reads ile değiştirerek en çok okuma yapan sorguları da görebilirsiniz. Okuma sayısı, sorgu iyileştirmede en güvenilir ölçüdür; nedenini T-SQL ayarında okumaların önemi yazımızda açıkladık.
Not
Plan önbelleği yalnızca önbellekte kalan planları gösterir; sunucu yeniden başladığında veya plan önbellekten düştüğünde geçmiş kaybolur. Kalıcı ve geriye dönük analiz için Query Store’u açık tutun.
6. Ne Değişti?
Daha önce hızlı çalışan bir sistem aniden yavaşladıysa, neredeyse her zaman bir şey değişmiştir:
| Değişiklik | Nasıl anlaşılır? | Ayrıntılı rehber |
|---|---|---|
| Yürütme planı değişti | Query Store’da aynı sorgu için yeni bir plan ve süre artışı | Query Store rehberi |
| Parametre hassasiyeti | Aynı sorgu bazı parametrelerle hızlı, bazılarıyla çok yavaş | Parameter sniffing |
| Yeni uygulama sürümü | Sürüm tarihinden sonra yeni sorgular veya artan çağrı sayısı | Sürüm notları ve yeni sorguların incelenmesi |
| Veri hacmi büyüdü | Yavaşlık yavaş yavaş arttı; tablo boyutları büyüdü | İndeks rehberi |
| Kilitlenmeler arttı | Deadlock sayısında artış | Deadlock rehberi |
| Yapılandırma değişti | Sunucu ayarları, uyumluluk seviyesi veya sanal makine kaynakları | Yapılandırma rehberi |
Sık Yapılan Teşhis Hataları
- Önce donanım eklemek: Verimsiz bir sorgu, iki katı CPU ile de verimsiz çalışır; yalnızca sorun bir süre ertelenir.
- Plan önbelleğini temizlemek:
DBCC FREEPROCCACHEanlık bir rahatlama sağlayabilir, ancak tüm planların yeniden derlenmesine yol açar ve sorunun kanıtını siler. - Herkesin aynı anda müdahale etmesi: Sanal makine ayarı, oturum sonlandırma ve ayar değişikliği aynı anda yapılınca hangisinin işe yaradığı anlaşılamaz.
- Sunucuyu yeniden başlatmak: Sorunu geçici olarak gizler, bekleme istatistiklerini ve önbelleği sıfırlar; kök neden bulunmadan sorun geri döner.
Performans ayarında sık yapılan diğer hataları 12 hata yazımızda topladık.
İpucu
Teşhise başlamadan önce mevcut durumun kanıtını toplayın: çalışan istekler, bekleme istatistikleri ve en pahalı sorgular. Bir yeniden başlatma veya plan temizliği bu bilgileri siler ve kök neden analizini imkânsız hale getirir.
Aryasoft ile SQL Server Performans İyileştirme
Aryasoft ekibi bir performans sorununa müdahale ederken önce izleme alarmlarına, hata loguna, aktif oturumlara, Agent işlerine, kaynak kullanımına, disk gecikmesine ve CPU’nun mantıksal işlemcilere dağılımına bakar. Darboğazı kanıtıyla gösterir, acil durumu kontrol altına alır ve ardından kalıcı çözümü uygular. Gerçek örnekler için kamu kurumunda %100 CPU vakasına ve CPU kullanımının %100’den %1’e düşürülmesine göz atabilirsiniz. Hizmet ayrıntıları SQL Server danışmanlık sayfamızda.
Sıkça Sorulan Sorular
Kaynaklar
Bu rehberdeki teknik bilgiler Kasım 2026’da aşağıdaki resmi dokümantasyonla karşılaştırıldı.
- Microsoft Learn: sys.dm_exec_requests
- Microsoft Learn: sys.dm_os_wait_stats
- Microsoft Learn: sys.dm_io_virtual_file_stats
- Microsoft Learn: sys.dm_exec_query_stats
- Microsoft Learn: Monitor performance by using the Query Store
- Microsoft Learn: Troubleshoot slow-running queries
SQL Server Performans
Darboğazı tahminle değil, kanıtla bulun
Aryasoft’un kıdemli SQL Server uzmanları sisteminizi inceler, sorunun kök nedenini gösterir ve kalıcı çözümü uygular.