Veritabanı İndeksleme ve Sorgu Optimizasyonu Rehberi: Yanıt Sürelerini Düşürme
Modern web sistemlerinde yavaş veritabanı darboğazını çözme adımları. EXPLAIN kullanımı, B-Tree/Composite indeksleme ve sorgu optimizasyonu teknikleri.
Sistem Yöneticisi
Kıdemli Yazılım Mimarı
Giriş: Yavaş Veritabanı Darboğazı
Modern web uygulamalarında yavaşlık sebebi genelde backend kodu değil, kötü SQL sorguları ve eksik indekslerdir. Dijital ajans projelerinde ve yüksek trafikli sistemlerde yanıt süresi doğrudan dönüşüm oranını etkiler. Bu rehber, sorgu sürelerini saniyelerden milisaniyelere indirme adımlarını kapsar.
Adım 1: Yavaş Sorguları Bulma (EXPLAIN ANALYZE)
Tahmin yapma. Önce ölç. PostgreSQL veya MySQL slow query log aç.
Plan Analizi
Sorgu önüne EXPLAIN ANALYZE koy. Çıktıda iki tehlikeli işlem ara:
- Seq Scan (Sequential Scan) / Full Table Scan: Tablodaki tüm satırlar okunur. Disk I/O tavan yapar.
- Temporary files / External sort: Bellek yetmediğinde diskte sıralama yapılır. Ciddi gecikme yaratır.
İpucu:Costtahmini değerdir.Actual timeveRows Removed by Filtergerçek darboğazı gösterir.
Adım 2: Doğru İndeks Türü Seçimi
Rastgele sütun indekslemek yazma (INSERT/UPDATE) maliyetini artırır. Sadece filtrelenen ve birleştirilen sütunları indeksle.
1. B-Tree İndeksi (Standart)
Eşitlik (=) ve aralık (<, >, BETWEEN) sorguları için varsayılan çözüm. Çoğu modern web senaryosunu çözer.
2. Composite (Bileşik) İndeks
Birden fazla sütun içeren WHERE filtreleri için tek indeks tanımla. Sütun sırası kritik: En seçici (high cardinality) sütun en başta olmalı.
CREATE INDEX idx_orders_user_status ON orders (user_id, status);3. Kapsayan İndeks (Covering Index)
Sorgudaki tüm sütunları indekse dahil et. Tablo diskine gitmeden (Index Only Scan) veriyi dön:
CREATE INDEX idx_users_active ON users (email) INCLUDE (name, created_at);Adım 3: Sorgu Refactoring (Yazım Hatalarını Düzeltme)
İndeks olsa bile kötü SQL yapısı indeksi devre dışı bırakır.
- SELECT * Kaldır: Sadece gereken sütunları çek. Network ve memory yükünü düşür.
- Fonksiyon İçi Filtreleme Yapma:
WHERE DATE(created_at) = '2025-01-01'indeksi bozar. Bunun yerine aralık kullan:WHERE created_at >= '2025-01-01' AND created_at < '2025-01-02'. - N+1 Sorgularını Birleştir: Döngü içinde SQL çalıştırma.
JOINveyaWHERE IN (...)kullan. - Offset Pagination Terk Et:
OFFSET 100000önceki tüm satırları tarar. Keyset pagination (Cursor) kullan:WHERE id > last_seen_id ORDER BY id ASC LIMIT 20.
Adım 4: Trendler ve Modern Veritabanı Yaklaşımları
Son trendler gereksiz disk kullanımını ve RAM şişmesini önleyen hafif çözümlere odaklanır:
- Partial (Koşullu) İndeksler: Sadece aktif kayıtları indeksle. Disk alanından %80 tasarruf:
CREATE INDEX idx_unpaid_invoices ON invoices (due_date) WHERE status = 'unpaid'; - BRIN İndeksleri: Zaman serisi (Time-series) ve log verilerinde devasa B-Tree indeksleri yerine minimal yer kaplayan Block Range Index tercih et.
- Kullanılmayan İndeksleri Temizle:
pg_stat_user_indexessorgula. Sıfır taranmış indeksleri sil.