Yavaş yazma (INSERT/UPDATE gecikmesi)
INSERT/UPDATE/DELETE işlemleri beklenenden yavaş. Önce yazmanın neyi beklediğini (commit/redo, lock, disk ya da satır başına ek maliyet) belirleyip adım adım kök nedene iniyoruz.
Yazma neyi bekliyor?
Wait event'lere bakarak darboğazı sınıfla: commit/redo (WAL) senkronizasyonu mu, lock mi, disk yazma gecikmesi mi, yoksa satır başına index/trigger maliyeti mi baskın?
SELECT event, total_waits, ROUND(time_waited/100,1) AS sec_waited
FROM v$system_event
WHERE event IN ('log file sync','log file parallel write','enq: TX - row lock contention','db file sequential read')
ORDER BY time_waited DESC;- Commit / redo (WAL sync) bekliyor
- Lock bekliyor
- Satır başına ek maliyet (index/trigger) şüphesi
- Disk yazma gecikmesi yüksek
Commit deseni mi, fsync mi?
Her satırda ayrı commit (autocommit) redo/log senkronizasyonunu satır sayısı kadar tetikler. Aksine commit sayısı makul ama her commit fsync'te bekliyorsa sorun log diskinin gecikmesindedir.
SELECT name, value FROM v$sysstat WHERE name IN ('user commits','redo writes','redo size');
SELECT ROUND(time_waited_micro/GREATEST(total_waits,1)/1000,2) AS ms_per_sync FROM v$system_event WHERE event='log file sync';- Autocommit / her satırda commit var
- Commit log senkronizasyonunda (fsync) bekliyor
Lock'u kim tutuyor?
Yazma bir lock için bekliyorsa: başka bir oturum aynı satırı/index'i tutuyor olabilir, ya da çok sayıda oturum aynı hot row'a yazmaya çalışıyor olabilir.
SELECT s.sid, s.serial#, s.username, s.blocking_session, s.event, s.seconds_in_wait
FROM v$session s WHERE s.blocking_session IS NOT NULL;- Başka oturum lock'u tutuyor
- Çok oturum aynı hot row'a yazıyor
Satır başına ek maliyet nereden?
Her INSERT/UPDATE, tablodaki tüm index'leri de günceller ve varsa trigger/constraint'leri çalıştırır. Aşırı index sayısı ya da ağır trigger, yazmayı ciddi yavaşlatır.
SELECT index_name, uniqueness FROM user_indexes WHERE table_name='T';
SELECT trigger_name, triggering_event FROM user_triggers WHERE table_name='T';- Tabloda çok fazla / gereksiz index var
- Ağır trigger veya constraint maliyeti var
Kök neden: Autocommit / satır başına commit
Her satır için ayrı commit, redo/log senkronizasyonunu satır sayısı kadar tekrarlar. Transaction'ları gruplayarak commit sayısını (dolayısıyla fsync sayısını) dramatik biçimde azaltabilirsin.
Kök neden: Yavaş redo/log diski (fsync gecikmesi)
Her commit, redo/WAL kaydını kalıcı diske yazana (fsync) kadar bekler. Log diski yavaşsa (yüksek yazma gecikmesi, IOPS yetersizliği), her commit bu gecikmeyi öder.
Kök neden: Başka oturum lock'u tutuyor
Yazma, başka bir oturumun tuttuğu satır/index lock'unu bekliyor. Genelde uzun süren ya da commit'i unutulmuş bir transaction engelleyicidir.
Kök neden: Hot row çekişmesi
Çok sayıda oturum aynı satıra (ör. bir sayaç, sıra numarası, bakiye) yazmaya çalışıyor; hepsi aynı lock için sıraya giriyor ve yazma serileşiyor.
Kök neden: Aşırı index maliyeti
Tablodaki her index, her yazmada güncellenir. Çok sayıda ya da kullanılmayan index, INSERT/UPDATE'i doğrudan yavaşlatır.
Kök neden: Ağır trigger / constraint
Yazma başına çalışan trigger veya doğrulanan constraint (özellikle index'siz foreign key kontrolü) her satıra ek maliyet bindirir.