"Sistem yavaşladı" şikâyeti geldiğinde ilk refleks genellikle sunucuyu büyütmek olur. Oysa çoğu durumda yükün büyük kısmını birkaç sorgu oluşturur ve doğru bir indeks, donanım yatırımından çok daha fazla fark yaratır. İzlediğimiz yol dört adımdan oluşuyor.
1. Önce ölçün: hangi sorgular zaman harcıyor?
pg_stat_statements eklentisi, sorguları normalize ederek toplam ve ortalama süreleriyle listeler. Toplam süreye göre sıralamak, en çok kaynak tüketen sorguları gösterir; tek seferlik yavaş bir sorgu yerine sık çalışan orta hızdaki bir sorgu çoğu zaman asıl sorundur.
SELECT calls,
round(total_exec_time) AS toplam_ms,
round(mean_exec_time, 1) AS ortalama_ms,
left(query, 120) AS sorgu
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;
2. Planı okuyun
Şüpheli sorguyu EXPLAIN (ANALYZE, BUFFERS) ile çalıştırın. ANALYZE sorguyu gerçekten çalıştırır; veri değiştiren sorguları bir işlem içinde deneyip geri almayı unutmayın.
EXPLAIN (ANALYZE, BUFFERS)
SELECT *
FROM tahakkuk
WHERE mukellef_id = 48213
AND yil = 2026
ORDER BY vade_tarihi;
Planda bakılacak üç şey var:
- Büyük bir tabloda Seq Scan: Satırların küçük bir kısmı isteniyorsa indeks eksik olabilir.
- Tahmini satır sayısı (rows) ile gerçek satır sayısı arasında büyük fark: İstatistikler güncel değildir veya sütunlar arasında planlayıcının bilmediği bir ilişki vardır.
- Sort veya Hash işlemlerinde diske taşma (external merge): work_mem yetersizdir ya da sıralama bir indeksle önlenebilir.
3. Sorguya uygun indeksi tasarlayın
Yukarıdaki sorgu için eşitlik koşulundaki sütunları önce, sıralama sütununu sonra koyan bileşik bir indeks; hem filtrelemeyi hem de sıralamayı tek seferde çözer.
CREATE INDEX CONCURRENTLY idx_tahakkuk_mukellef_yil_vade
ON tahakkuk (mukellef_id, yil, vade_tarihi);
Canlı sistemde
CONCURRENTLY seçeneği, indeks oluşturulurken tabloya yazmayı engellemez. Daha uzun sürer ama canlı bir sistemde kesinti yaratmaz. Her yeni indeksin yazma işlemlerine ek maliyet getirdiğini de unutmayın; kullanılmayan indeksleri pg_stat_user_indexes ile düzenli olarak gözden geçirin.
4. Doğrulayın ve izleyin
İndeksten sonra aynı EXPLAIN (ANALYZE, BUFFERS) komutunu tekrar çalıştırın; Index Scan görmeli ve okunan blok sayısının düştüğünü doğrulamalısınız. Ardından pg_stat_statements istatistiklerini sıfırlayıp birkaç gün sonra tekrar bakın: Asıl ölçü, tek bir sorgunun hızı değil, sistemin toplamda harcadığı süredir.
Aynı yaklaşım Oracle tarafında da geçerlidir; araçlar farklıdır (AWR raporları, SQL Monitor, yürütme planları), ama sıra aynıdır: ölç, planı oku, hedefli değiştir, doğrula.
