IHS Strategic
Tüm Blog Yazıları
HowTo09 Eylül 2026•2 dk okuma

Veritabanı İndeksleme ve Sorgu Optimizasyonu Rehberi: Yanıt Sürelerini Azaltma

Yavaş SQL sorgularını tespit etme, doğru indeks tipi seçme ve veritabanı yanıt sürelerini milisaniyelere düşürme adımları. Modern web sistemleri için performans rehberi.

S

Sistem Yöneticisi

Kıdemli Yazılım Mimarı

Giriş: Neden Sorgu Optimizasyonu?

Modern web uygulamalarında yavaşlık sebebi genelde sunucu CPU değil, kötü SQL sorguları. Dijital ajans projelerinde veritabanı darboğazı sayfa açılışını bozar. Çözüm: Doğru indeksleme ve sorgu refactor.

Adım 1: Yavaş Sorguları Tespit Et

Önce ölçüm. Ezbere optimizasyon yok. Slow query log aktif et.

  • PostgreSQL: pg_stat_statements eklentisi kur. mean_exec_time yüksek sorguları bul.
  • MySQL: slow_query_log = 1 ve long_query_time = 0.5 ayarla.

Adım 2: EXPLAIN ve EXPLAIN ANALYZE ile Yürütme Planını Oku

Sorgu motorunun ne yaptığını gör. EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com'; çalıştır.

  • Sequential Scan / Table Scan: Kötü. Tüm disk taranır. İndeks yok demek.
  • Index Scan / Index Only Scan: İyi. Doğrudan indeks ağacından veri çeker.
  • Cost ve Actual Time: Maliyet yüksekse indeks stratejisini değiştir.

Adım 3: Doğru İndeks Tipini Uygula

Her kolona indeks atma. Yazma (INSERT/UPDATE) maliyeti artar. Amaca uygun indeks seç.

B-Tree İndeks (Standart)

Eşitlik (=) ve aralık (>, <, BETWEEN) sorguları için varsayılan tip.

CREATE INDEX idx_orders_created_at ON orders(created_at);

Bileşik (Composite) İndeks

Birden fazla kolonla filtreleme varsa tek indeks yap. Kolon sırası kritik: En seçici (high cardinality) kolon başta olmalı.

CREATE INDEX idx_users_status_created ON users(status, created_at);

Kısmi (Partial) İndeks

Tablonun sadece küçük bir kısmını sorguluyorsan tüm tabloyu indeksleme. Disk ve RAM tasarrufu sağlar.

CREATE INDEX idx_active_users ON users(id) WHERE status = 'active';

Adım 4: Sorgu Yazım Hatalarını Düzelt

İndeks olsa bile sorgu yanlış yazılırsa veritabanı indeksi görmezden gelir.

  • İndeksli kolonda fonksiyon kullanma: WHERE DATE(created_at) = '2023-01-01' indeksi bozar. Yerine: WHERE created_at >= '2023-01-01 00:00:00' AND created_at < '2023-01-02 00:00:00'.
  • SELECT * yapma: Yalnızca gereken kolonları çek. Index Only Scan şansını yok etme. Network ve bellek yükünü azalt.
  • N+1 sorgu probleminden kaçın: Döngü içinde sorgu atma. JOIN veya WHERE id IN (...) kullan.
  • Leading Wildcard LIKE yapma: LIKE '%abc' B-Tree indeksi kullanamaz. Full text search veya Trigram (pg_trgm) indeks kullan.
İpucu: Modern web trendleri gereği mikroservis mimarilerinde bağlantı havuzu (Connection Pooler örn. PgBouncer) kullanmak, sorgu süresi kadar bağlantı açma maliyetini de optimize eder.

Adım 5: İndeks Bakımı ve Temizliği

Kullanılmayan indeksler sisteme safi yük. Periyodik olarak kontrol et ve sil.

  • PostgreSQL kullanılmayan indeks tespiti: SELECT * FROM pg_stat_user_indexes WHERE idx_scan = 0;
  • Gereksiz indeksi sil: DROP INDEX CONCURRENTLY idx_name; (Tabloyu kilitlememek için CONCURRENTLY kullan).