Veritabanı İndeksleme ve Sorgu Optimizasyonu: Kapsamlı Performans Rehberi
Veritabanı darboğazlarını tespit etme, indeksleme stratejileri kurma ve sorgu optimizasyonuyla modern web uygulamalarında milisaniye seviyesinde yanıt süreleri elde etme rehberi.
Sistem Yöneticisi
Kıdemli Yazılım Mimarı
Giriş: Neden Sorgu Optimizasyonu?
Modern web mimarilerinde yüksek gecikme sürelerinin birincil kaynağı veritabanı I/O işlemleridir. Bir dijital ajans veya kurumsal yazılım ekibi için sayfa yükleme hızları, doğrudan kullanıcı deneyimi ve dönüşüm oranlarını belirler. Bu rehber, yavaş sorguları tespit etme, doğru indeksleme tiplerini uygulama ve sorgu çalıştırma maliyetlerini minimize etme adımlarını içerir.
1. Adım: Yavaş Çalışan Sorguları Tespit Etme
Optimizasyona başlamadan önce darboğaz oluşturan sorgular ölçülmelidir. Varsayımlarla indeks eklemek gereksiz yazma maliyeti üretir.
- Slow Query Log Aktif Edin: PostgreSQL için
log_min_duration_statement, MySQL içinslow_query_logdeğerlerini yapılandırın. - Query Execution Plan Çıkarın: Sorgunun önüne
EXPLAIN ANALYZEekleyerek maliyeti (cost), taranan satır sayısını ve kullanılan indeksleri inceleyin.
İpucu:Seq Scan(Sequential Scan) veyaALL(Full Table Scan) görüyorsanız, sorgu tablonun tamamını okuyor demektir. İndeks ihtiyacının en net işaretidir.
2. Adım: Doğru İndeks Türünü Seçme ve Uygulama
Her kolon aynı mantıkla indekslenemez. Modern veritabanı sistemlerinde veri tipine ve sorgu desenine uygun indeks seçilmelidir.
B-Tree İndeksleri
Varsayılan indeks tipidir. Eşitlik (=) ve aralık (<, >, BETWEEN) sorgularında en yüksek performansı verir.
CREATE INDEX idx_users_email ON users(email);Bileşik (Composite) İndeksler
Birden fazla kolon üzerinde filtreleme veya sıralama yapılıyorsa kullanılır. Kolon sırası kritik önem taşır (Leftmost Prefix Kuralı).
CREATE INDEX idx_orders_status_created ON orders(status, created_at DESC);Kısmi (Partial / Filtered) İndeksler
Tablonun sadece belirli bir alt kümesini indeksleyerek disk alanı ve yazma maliyetinden tasarruf sağlar.
CREATE INDEX idx_active_subscriptions ON subscriptions(user_id) WHERE status = 'active';3. Adım: SQL Sorgu Kalıplarını Optimize Etme
İndeks varlığı tek başına yetersizdir; sorgunun indeksi kullanabilir formatta yazılması gerekir.
- Kolon Üzerinde Fonksiyon Kullanmayın:
WHERE DATE(created_at) = '2023-01-01'yerineWHERE created_at >= '2023-01-01' AND created_at < '2023-01-02'kalıbını tercih edin. Kolon fonksiyona sarıldığında B-Tree indeksi devre dışı kalır. - Wildcard Pozisyonu:
LIKE '%aranan'aramaları indeksi kullanamaz. MümkünseLIKE 'aranan%'veya Full-Text Search (GIN/GiST) indeksleri kullanın. - Gereksiz SELECT * İfadelerini Kaldırın: Sadece ihtiyaç duyulan kolonları seçin. Bu sayede Covering Index (Index-Only Scan) mekanizması devreye girer ve disk okuması sıfıra iner.
- N+1 Problemini Giderin: ORM kullanımlarında ilişkili tabloları döngü içinde tek tek çekmek yerine
JOINveyaEager Loading(include/with) kalıplarıyla tek seferde getirin.
4. Adım: Veritabanı Bakımı ve Güncel Trendler
Modern web altyapılarında veri hacmi arttıkça veritabanı motorunun istatistikleri güncelliğini yitirir.
- İstatistikleri Güncel Tutun: Sorgu planlayıcının doğru kararlar vermesi için periyodik olarak
ANALYZEkomutunu çalıştırın. - Kullanılmayan İndeksleri Temizleyin: Her indeks
INSERT,UPDATEveDELETEişlemlerini yavaşlatır. Sistem kataloglarından kullanılmayan indeksleri tespit edip silin. - Trend Yaklaşımlar: Read-Replica ayrımı, connection pooling (PgBouncer) ve analitik yükler için Columnar depolama formatları modern mimarilerde standart haline gelmiştir.
Özet Kontrol Listesi
- [ ] Slow query log üzerinden en çok kaynak tüketen sorgular çıkarıldı mı?
- [ ] EXPLAIN ANALYZE çıktısında Full Table Scan yapan yerler tespit edildi mi?
- [ ] Filtreleme ve sıralama kombinasyonları için bileşik indeksler eklendi mi?
- [ ] WHERE koşullarındaki fonksiyon çağrıları temizlendi mi?
- [ ] SELECT sorguları sadece gerekli alanları çekecek şekilde sınırlandı mı?