IHS Strategic
Tüm Blog Yazıları
HowTo10 Eylül 2026•3 dk okuma

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.

S

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çin slow_query_log değerlerini yapılandırın.
  • Query Execution Plan Çıkarın: Sorgunun önüne EXPLAIN ANALYZE ekleyerek maliyeti (cost), taranan satır sayısını ve kullanılan indeksleri inceleyin.
İpucu: Seq Scan (Sequential Scan) veya ALL (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' yerine WHERE 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ünse LIKE '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 JOIN veya Eager 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 ANALYZE komutunu çalıştırın.
  • Kullanılmayan İndeksleri Temizleyin: Her indeks INSERT, UPDATE ve DELETE iş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ı?