Performans
PostgreSQL performans optimizasyonu: nereden başlamalı?
Panik hâlinde rastgele indeks eklemek yerine, ölçülebilir bir yöntemle ilerlemek; çoğu sistemde ilk birkaç günde büyük kazanım sağlar.
18 Ağustos 20269 dakika okumaYazan: ScaleOn ekibi
Bir uygulamanın “yavaş” olması genellikle veritabanının tamamının değil, birkaç sorgunun sorunudur. Bu yazıda, üretim ortamında güvenle uygulayabileceğiniz bir sıralama öneriyoruz: önce ölç, sonra en pahalı işe odaklan, değişikliği doğrula.
1. Ölçüm: en pahalı sorguları bul
pg_stat_statements eklentisi, performans çalışmasının temelidir. Toplam süreye göre ilk 20 sorgu, çoğunlukla iş yükünün büyük kısmını temsil eder.
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
SELECT
round(total_exec_time::numeric, 1) AS toplam_ms,
calls,
round(mean_exec_time::numeric, 2) AS ort_ms,
round((100 * total_exec_time / sum(total_exec_time) OVER ())::numeric, 1) AS pay_yuzde,
query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;
“Ortalama hızlı ama çok sık çağrılıyor” tipi sorgular da en az “tekil olarak yavaş” sorgular kadar önemlidir; pay_yuzde kolonu bunu görünür kılar.
2. Teşhis: EXPLAIN (ANALYZE, BUFFERS) okuma
Şüpheli sorguyu gerçek verilerle çalıştırıp planını inceleyin:
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT ...;
Bakılacak başlıca işaretler:
- Seq Scan büyük bir tabloda ve seçici bir
WHEREile birlikteyse, indeks eksik olabilir. - Rows Removed by Filter yüksekse, veritabanı gereğinden çok satır okuyup atıyor demektir.
- tahmini satır ≠ gerçek satır (büyük sapma) genelde eski istatistik ya da bağ (correlation) sorununa işaret eder;
ANALYZE tablo;çalıştırın. - Nested Loop beklenmedik biçimde büyük dış küme ile çalışıyorsa, join sırası veya indeks sorunu vardır.
- shared read (BUFFERS) yüksekse, çalışma kümesi bellek dışına taşıyor olabilir.
3. İndeks stratejisi
Sık uygulanan, düşük riskli iyileştirmeler:
- Bileşik indeks sırası: eşitlik filtreleri önce, aralık filtresi ve sıralama kolonu sonra.
- Örtük (covering) indeks:
INCLUDE (...)ile sık okunan kolonları ekleyip index-only scan'i mümkün kılın. - Kısmi indeks:
WHERE status = 'active'gibi sorguların büyük kısmı küçük bir alt kümeye bakıyorsa. - İfade indeksi:
lower(email)gibi fonksiyonla filtreliyorsanız aynı ifadeye indeks verin — ya da filtreyi sargable hâle getirin.
Yeni indeksi üretimde CREATE INDEX CONCURRENTLY ile ekleyin; tabloyu uzun süre kilitlemez. Eklemeden önce yazma maliyetini de düşünün: her indeks, INSERT/UPDATE/DELETE işlemlerini bir miktar yavaşlatır. pg_stat_user_indexes ile hiç kullanılmayan indeksleri tespit edip kaldırmak da bir kazanımdır.
4. Sorgu ve şema düzeltmeleri
- Sargable filtreler:
WHERE date(created_at) = ...yerinecreated_at >= ... AND created_at < .... - Keyset sayfalama: derin
OFFSETyerine son görülen anahtardan devam edin. - N+1: ORM'in döngü içinde tek tek sorgu atmasını, tek bir
JOINveyaINile birleştirin. - Gereksiz kolon çekmeyin:
SELECT *, index-only scan'i ve ağ verimliliğini bozar.
5. Autovacuum ve istatistikler
Yoğun güncellenen tablolarda varsayılan autovacuum eşiği çok yüksek kalır; ölü satırlar (bloat) birikir ve planlayıcı yanılır. Tablo bazında sıkılaştırın:
ALTER TABLE order_lines SET (
autovacuum_vacuum_scale_factor = 0.02,
autovacuum_analyze_scale_factor = 0.01
);
pg_stat_user_tables içindeki n_dead_tup, last_autovacuum ve last_autoanalyze kolonları, ayarın işe yarayıp yaramadığını gösterir.
6. Birkaç yapılandırma parametresi
shared_buffers: tipik olarak RAM'in ~%25'i.effective_cache_size: işletim sistemi önbelleği dahil beklenen toplam; planlayıcıyı etkiler.work_mem: sıralama/hash için; oturum ve operasyon başına ayrıldığı için temkinli artırın.random_page_cost: SSD'de 1.1 civarı, indeks kullanımını teşvik eder.
7. Doğrulama ve kalıcılaştırma
Her değişikliğin öncesi/sonrası mean_exec_time ve total_exec_time değerini kaydedin. Kazanımı koruyacak bir uyarı ekleyin: örneğin “bu sorgunun p95 süresi 500 ms'yi aşarsa bildir”. Aksi hâlde birkaç ay sonra aynı sorunla yeniden karşılaşırsınız.
pg_stat_statements ile en pahalı 20 sorguyu çıkarın → her biri için EXPLAIN (ANALYZE, BUFFERS) → sargable filtre + hedefli indeks + keyset sayfalama → yoğun tablolarda autovacuum sıkılaştırma → öncesi/sonrası kıyas ve uyarı.
Kendi ortamınızda bu adımları birlikte uygulamamızı ister misiniz? Performans optimizasyonu hizmetimize göz atın ya da kısa bir görüşme planlayın.