Deney düzeneği
bank_txns tablosunda yaklaşık 42.000 hesap hareketi var. Tabloda yalnızca birincil anahtar ve account_id üzerinde indeks bulunuyor; txn_time, txn_type ve merchant_category indekssiz. Her kod kutusunun altında sorgunun tarayıcıda kaç milisaniye sürdüğü yazar. Kutuları sırayla çalıştır ve süreleri karşılaştır.
1) İndekssiz: tarih aralığı
SELECT COUNT(*) AS islem, ROUND(SUM(-amount), 0) AS harcama FROM bank_txns WHERE txn_time >= '2024-12-24' AND txn_time < '2024-12-25' AND txn_type = 'kart_harcama';
EXPLAIN QUERY PLAN SELECT COUNT(*) FROM bank_txns WHERE txn_time >= '2024-12-24' AND txn_time < '2024-12-25';
Planda SCAN bank_txns görürsün: tüm tablo okunuyor.
2) İndeks ekle, aynı sorguyu tekrar çalıştır
CREATE INDEX ix_txn_time ON bank_txns (txn_time); SELECT COUNT(*) AS islem, ROUND(SUM(-amount), 0) AS harcama FROM bank_txns WHERE txn_time >= '2024-12-24' AND txn_time < '2024-12-25' AND txn_type = 'kart_harcama';
CREATE INDEX ix_txn_time ON bank_txns (txn_time); EXPLAIN QUERY PLAN SELECT COUNT(*) FROM bank_txns WHERE txn_time >= '2024-12-24' AND txn_time < '2024-12-25';
Plan artık SEARCH bank_txns USING INDEX ix_txn_time diyor: yalnızca ilgili aralık okunuyor.
3) Fonksiyon indeksi bozar
CREATE INDEX ix_txn_time ON bank_txns (txn_time); EXPLAIN QUERY PLAN SELECT COUNT(*) FROM bank_txns WHERE date(txn_time) = '2024-12-24';
İndeks var ama sütun date() fonksiyonunun içinde olduğu için yine tüm tablo taranır.
4) Bileşik ve kapsayan indeks (covering index)
CREATE INDEX ix_tip_zaman ON bank_txns (txn_type, txn_time, amount); EXPLAIN QUERY PLAN SELECT SUM(amount) FROM bank_txns WHERE txn_type = 'maas' AND txn_time >= '2024-06-01' AND txn_time < '2024-07-01';
USING COVERING INDEX: sorgunun ihtiyaç duyduğu tüm sütunlar indekste olduğu için tabloya hiç gidilmez. Eşitlik koşulu olan sütun (txn_type) önce, aralık koşulu olan (txn_time) sonra gelir.
Gerçek SQL türlerinde plan okumak
-- SQL Server SET STATISTICS IO, TIME ON; -- Yürütme planı: Ctrl+M (gerçek plan), Index Seek / Index Scan / Key Lookup -- PostgreSQL EXPLAIN (ANALYZE, BUFFERS) SELECT ...; -- Seq Scan, Index Scan, Index Only Scan, Bitmap Heap Scan -- MySQL EXPLAIN ANALYZE SELECT ...; -- type: ALL (tam tarama), range, ref, const -- Oracle EXPLAIN PLAN FOR SELECT ...; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); -- TABLE ACCESS FULL, INDEX RANGE SCAN -- BigQuery: yürütme ayrıntıları sekmesi ve taranan bayt; indeks yerine bölümleme/kümeleme