DBAtlas · Veritabanı operasyon atlası

Yavaş sorgu — derinlemesine tanı

Bir sorgu ya da sistem yavaş. Adım adım daralt: her düğümde bir kontrol çalıştır, sonucuna göre dalı seç. Sonunda kök neden + çözüm.

Yavaş olan ne?

Belirli bir/birkaç sorgu mu yavaş, yoksa tüm sistem mi? Bu, aramayı 'sorgu odaklı' ya da 'kaynak/darboğaz odaklı' iki koldan birine ayırır.

  • Belirli bir/birkaç sorgu yavaş
  • Tüm sistem geneli yavaş

Sorgu şu an mı çalışıyor?

O an çalışan/takılı bir sorgu mu, yoksa 'genelde yavaş' bir sorgu mu? Aktif oturumlara bak.

SELECT sid, serial#, sql_id, last_call_et AS running_sec, event, blocking_session
FROM v$session WHERE status='ACTIVE' AND type='USER' ORDER BY last_call_et DESC;
  • Şu an çalışıyor / takılı
  • Genelde yavaş — planına bakmak istiyorum

Sorgu bir şey mi bekliyor?

Aktif ama ilerlemiyorsa büyük ihtimalle bekliyordur. blocking_session / wait_event dolu mu?

SELECT sid, blocking_session, event, seconds_in_wait
FROM v$session WHERE sid=&hedef_sid;
  • Başka bir oturum tarafından bloklanıyor
  • Bir kaynağı bekliyor (IO / log / latch)
  • Bekleme yok, aktif CPU yiyor

Hangi bekleme baskın?

Baskın wait event darboğazın türünü söyler.

SELECT event, total_waits, time_waited FROM v$session_event WHERE sid=&hedef_sid ORDER BY time_waited DESC FETCH FIRST 5 ROWS ONLY;
  • IO bekleme (db file read / PAGEIOLATCH)
  • Log / commit bekleme (log file sync / WRITELOG)
  • Lock / enqueue (enq: TX / LCK)

Çalışma planını (EXPLAIN) al

Planı çıkar. Tam tablo taraması (full scan), beklenmedik join sırası, ya da tahmini-vs-gerçek satır farkı var mı?

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('&sql_id', NULL, 'ALLSTATS LAST'));
  • Full scan / eksik index var
  • Dün hızlıydı, plan aniden değişti
  • Çok fazla satır işliyor / N+1
  • Plan iyi görünüyor ama yavaş

İstatistikler güncel mi?

Tahmini satır ile gerçek satır (E-rows vs A-rows) arasında büyük fark, bayat istatistiğin işaretidir.

SELECT table_name, num_rows, last_analyzed FROM dba_tables WHERE table_name='&TABLO';
  • İstatistik bayat / eski
  • İstatistik güncel ama yine yavaş

Sistem geneli — darboğaz neresi?

Tek sorgu değil her şey yavaşsa kaynak darboğazına bak: CPU mu, IO mu, bellek mi, yoksa yaygın bloklama mı?

SELECT metric_name, value FROM v$sysmetric WHERE metric_name IN ('Host CPU Utilization (%)','Average Active Sessions') AND intsize_csec=(SELECT MAX(intsize_csec) FROM v$sysmetric);
  • CPU %100'e yakın
  • IO bekleme yüksek
  • Bellek baskısı / düşük cache hit
  • Çok sayıda bloklama

Kök neden: Bloklama

Sorgu, başka bir oturumun tuttuğu lock'u bekliyor. Zincirin başındaki (root blocker) oturumu bul ve çöz.

Kök neden: IO darboğazı

Sorgu diskten çok okuyor. Genelde full scan (eksik index) ya da yetersiz bellek (buffer cache) yüzünden.

Kök neden: Commit / log darboğazı

'log file sync' / 'WRITELOG' baskınsa, commit'ler redo/WAL yazımını bekliyordur.

Kök neden: Eksik index

Plan full scan yapıyor. Filtre/join kolonlarına uygun index büyük hızlanma sağlar.

Kök neden: Plan regresyonu

Sorgu dün hızlıydı, bugün değil — plan değişmiş. Genelde bayat istatistik veya parametre değişimi.

Kök neden: Sorgu tasarımı

Plan mantıklı ama sorgu doğası gereği çok iş yapıyor (çok satır, N+1, gereksiz join).

Kök neden: Bayat istatistik

Optimizer yanlış tahmin ediyor çünkü istatistikler güncel değil.

Derinlemesine analiz

Plan ve istatistik iyi ama hâlâ yavaşsa daha derine in.

Kök neden: CPU darboğazı

Tüm sistem CPU'ya takılı. Genelde birkaç kötü planlı sorgu CPU'yu yakar.

Kök neden: Bellek baskısı

Düşük cache hit ve/veya swap: bellek yetersiz ya da yanlış dağıtılmış.

DBAtlas'ta aç →