Veritabanı Index Nedir? Sorgu Performansını 100x Artırma
Veritabanı sorguları yavaş mı? Milyon satırlık tabloda arama saniyeler mi sürüyor? Index ile sorgu performansınızı dramatik şekilde artırın.
Index Tanımı
Veritabanı indexi, bir kitabın fihristine benzer. Kitabın tamamını okumak yerine, fihristten ilgili sayfaya direkt gidersiniz. Index olmadan veritabanı tüm tabloyu baştan sona tarar (Full Table Scan).
Index olmadan: 1.000.000 satır → Hepsini tara → 2.5 saniye
Index ile: 1.000.000 satır → Index'ten bul → 0.003 saniye
Index Nasıl Çalışır?
B-Tree Index (Varsayılan)
En yaygın index türü. Dengeli ağaç (balanced tree) yapısı kullanır:
[M]
/ \
[D,H] [R,V]
/ | \ / | \
[A-C][E-G][I-L][N-Q][S-U][W-Z]
- =, <, >, BETWEEN, LIKE 'abc%' sorguları için ideal
- O(log n) karmaşıklık — 1 milyon satırda sadece ~20 karşılaştırma
Hash Index
- Sadece = eşitlik kontrolleri için
- O(1) karmaşıklık — çok hızlı ama range sorguları desteklemez
Index Türleri
1. Primary Key Index
CREATE TABLE users (
id SERIAL PRIMARY KEY, -- Otomatik index
email VARCHAR(255),
name VARCHAR(100)
);
2. Unique Index
CREATE UNIQUE INDEX idx_users_email ON users(email);
-- Aynı e-posta iki kere kaydedilemez
3. Composite Index (Bileşik)
CREATE INDEX idx_orders_customer_date
ON orders(customer_id, order_date DESC);
-- Bu index şu sorguları hızlandırır:
-- WHERE customer_id = 42
-- WHERE customer_id = 42 AND order_date > '2026-01-01'
-- ORDER BY customer_id, order_date DESC
-- AMA bunu hızlandırMAZ:
-- WHERE order_date > '2026-01-01' (ilk kolon olmadan)
4. Partial Index
CREATE INDEX idx_active_orders ON orders(customer_id)
WHERE status = 'active';
-- Sadece aktif siparişleri indexler, daha küçük ve hızlı
5. Full-Text Index
CREATE INDEX idx_posts_search ON posts USING gin(to_tsvector('turkish', content));
-- Metin arama için özel index
EXPLAIN ANALYZE ile Sorgu Analizi
EXPLAIN ANALYZE
SELECT * FROM orders WHERE customer_id = 42;
Çıktı:
Index Scan using idx_orders_customer on orders
Index Cond: (customer_id = 42)
Actual time: 0.025..0.031 (ms)
Rows: 15
Kötü sorgu (Full Table Scan):
Seq Scan on orders
Filter: (customer_id = 42)
Actual time: 125.432..130.567 (ms)
Rows: 15 (1.000.000 tarandı)
Ne Zaman Index Oluşturmalı?
✅ Index Oluşturun:
- WHERE koşullarında sık kullanılan kolonlar
- JOIN koşullarındaki FK kolonlar
- ORDER BY ile sıralama yapılan kolonlar
- Unique olması gereken kolonlar
❌ Index Oluşturmayın:
- Çok az satırlı tablolarda (<1000)
- Çok sık güncellenen kolonlarda
- Düşük kardinaliteli kolonlarda (boolean gibi)
- Her kolona — her index yazma maliyeti ekler
Index Maliyeti
SELECT: Index → Daha hızlı ✅
INSERT: Index → Daha yavaş ❌ (index güncellenmeli)
UPDATE: Index → Daha yavaş ❌ (index güncellenmeli)
DELETE: Index → Daha yavaş ❌ (index güncellenmeli)
PostgreSQL Index İpuçları
-- Kullanılmayan index'leri bul
SELECT indexrelname, idx_scan
FROM pg_stat_user_indexes
WHERE idx_scan = 0
ORDER BY pg_relation_size(indexrelid) DESC;
-- Index boyutlarını gör
SELECT pg_size_pretty(pg_indexes_size('orders'));
-- Index durumunu kontrol et
REINDEX INDEX idx_orders_customer;
Best Practices
- EXPLAIN ANALYZE ile sorguları analiz edin
- Composite index sıralamasına dikkat — en seçici kolonu başa koyun
- Kullanılmayan index'leri silin — Yazma performansını olumsuz etkiler
- Partial index kullanın — Sadece ihtiyaç duyulan alt kümeyi indexleyin
- VACUUM ve ANALYZE düzenli çalıştırın — İstatistikleri güncel tutun
- Covering index düşünün —
INCLUDEile ek kolonları indexe ekleyin
Sonuç
Doğru index stratejisi, veritabanı performansınızı 10x-100x artırabilir. Ancak her index yazma maliyeti getirir. EXPLAIN ANALYZE ile ölçün, gereksiz index'leri temizleyin ve veri erişim desenlerinize uygun index'ler oluşturun.
Veritabanı optimizasyonu ve index stratejilerini LabLudus platformunda öğrenin.