İndeks = kitabın arkasındaki dizin
İndeks olmadan veritabanı bir koşulu sağlayan satırları bulmak için tüm tabloyu tarar (full table scan / SQL Server'da Table Scan). İndeks, sütun değerlerini sıralı bir B-tree yapısında tutar ve aramayı logaritmik zamana indirir.
Sorgu planını görmek
| SQL türü | Planı görme |
|---|---|
| SQL Server | SSMS'te Ctrl+M (gerçek plan) veya SET SHOWPLAN_TEXT ON |
| PostgreSQL | EXPLAIN, EXPLAIN ANALYZE |
| MySQL | EXPLAIN, EXPLAIN ANALYZE (8.0.18+) |
| Oracle | EXPLAIN PLAN FOR ... + DBMS_XPLAN.DISPLAY |
| SQLite | EXPLAIN QUERY PLAN |
Tarayıcıdaki motor SQLite olduğu için aşağıdaki kutular hangi SQL türü seçersen seç SQLite planını gösterir; yazım farkını sekmelerde görebilirsin.
EXPLAIN QUERY PLAN SELECT * FROM orders WHERE customer_id = 42;
Çıktıda SCAN orders görürsün: tablo baştan sona taranıyor. Şimdi indeks ekleyelim:
CREATE INDEX idx_orders_customer ON orders(customer_id); EXPLAIN QUERY PLAN SELECT * FROM orders WHERE customer_id = 42;
Artık SEARCH orders USING INDEX idx_orders_customer (SQL Server'da Index Seek, PostgreSQL'de Index Scan).
Ne zaman indeks?
- WHERE, JOIN ON ve ORDER BY'da sık kullanılan, seçici (çok farklı değer içeren) sütunlar.
- Yabancı anahtar sütunları (JOIN'ler için).
- Bileşik indeks
(a, b):WHERE a = ?veWHERE a = ? AND b = ?için çalışır, sadeceWHERE b = ?için genelde çalışmaz (soldan önek kuralı).
INCLUDE (sütunlar) ile kapsayan (covering) indeks yapılabilir. T-SQL modülünde ayrıntılı işliyoruz.Bedeli
- Her INSERT/UPDATE/DELETE indeksleri de günceller; yazma yavaşlar.
- Disk alanı kaplar.
- Sütuna fonksiyon uygularsan indeks kullanılamayabilir:
WHERE YEAR(order_date) = 2024yerine aralık yaz:order_date >= '2024-01-01' AND order_date < '2025-01-01'. Bu kurala SQL Server dünyasında SARGable sorgu denir.
İş senaryosu: müşteri ekranı
Anadolu Market çağrı merkezi müşterinin siparişlerini açıyor. Sorgu customer_id ile arıyor ve günde binlerce kez çalışıyor. Önce planı oku, sonra indeks ekle. Plan SCAN iken indeks yoksa, indeks eklendikten sonra SEARCH olmalıdır. Hem status hem tarih aranıyorsa ve sütun sırası yanlışsa plan parantezinde tek sütun görünür.
CREATE INDEX ix_orders_tarih_durum ON orders (order_date, status); EXPLAIN QUERY PLAN SELECT COUNT(*) FROM orders WHERE status = 'delivered' AND order_date >= '2024-11-01';
CREATE INDEX ix_orders_durum_tarih ON orders (status, order_date); EXPLAIN QUERY PLAN SELECT COUNT(*) FROM orders WHERE status = 'delivered' AND order_date >= '2024-11-01';
Devamı için Sorgu Optimizasyonu öğrenme yoluna bak: plan okuma, sütun sırası, kapsayan indeks, seçicilik ve yanlış optimizasyon örnekleri orada ayrı derslerdir.