← Kursa Dön
📄 Text · 30 min

Index Stratejileri: Covering, Prefix Index

Covering Index — Tabloya Gitmeden Sonuç

Eğer sorgunun ihtiyaç duyduğu tüm sütunlar index'te varsa, MySQL tabloya hiç gitmez — sadece index'ten cevap verir. Bu covering index olarak adlandırılır.

-- Composite index oluştur
CREATE INDEX idx_city_name ON customers(city, first_name, last_name);

-- Bu sorgu sadece index'ten cevap alır (covering index)
EXPLAIN SELECT first_name, last_name FROM customers WHERE city = 'İstanbul';
-- Extra: Using index ← tabloya gitmeden!

-- Bu sorgu tabloya da gider (email index'te yok)
EXPLAIN SELECT first_name, email FROM customers WHERE city = 'İstanbul';
-- Extra: (Using index yok) — email için tabloya gitmek zorunda

💡 Covering index özellikle SELECT'teki sütunlar az olduğunda çok etkilidir.


Prefix Index — Uzun String'ler İçin

Uzun VARCHAR veya TEXT sütunlarında tam index çok yer kaplar. Prefix index sadece ilk N karakteri indexler:

-- İlk 10 karakter indexlenir
CREATE INDEX idx_name_prefix ON products(product_name(10));

-- E-posta domain'i genellikle @ sonrası — prefix index etkili olmayabilir
-- Ama kısa alan adlarında işe yarar
CREATE INDEX idx_email_prefix ON customers(email(20));

Prefix uzunluğunu belirleme:

-- Kaç karakter yeterli? Selectivity analizi
SELECT 
    COUNT(DISTINCT LEFT(product_name, 5)) AS prefix_5,
    COUNT(DISTINCT LEFT(product_name, 10)) AS prefix_10,
    COUNT(DISTINCT LEFT(product_name, 15)) AS prefix_15,
    COUNT(DISTINCT product_name) AS full_name
FROM products;
-- prefix_10 ≈ full_name ise 10 karakter yeterli

Functional Index (MySQL 8.0.13+)

-- Fonksiyon sonucunu indexle
CREATE INDEX idx_year ON orders ((YEAR(order_date)));
CREATE INDEX idx_lower_email ON customers ((LOWER(email)));

-- Artık bu sorgular index kullanır:
SELECT * FROM orders WHERE YEAR(order_date) = 2024;
SELECT * FROM customers WHERE LOWER(email) = 'test@email.com';

Index Stratejisi Seçimi

SenaryoStrateji
WHERE city = ?Tekli index
WHERE city = ? AND status = ?Composite index
SELECT a, b WHERE a = ?Covering index (a, b)
WHERE LOWER(email) = ?Functional index
WHERE name LIKE 'abc%'Normal index (prefix match)
WHERE name LIKE '%abc%'FULLTEXT index
Uzun TEXT sütunuPrefix index

Özet

  • Covering index: sorgunun tüm sütunları index'te → tabloya gitmeden sonuç

  • Prefix index: uzun string'lerin ilk N karakterini indexler → disk tasarrufu

  • Functional index: fonksiyon sonucunu indexler (MySQL 8.0.13+)

  • EXPLAIN'de "Using index" → covering index çalışıyor

  • Selectivity analizi yaparak prefix uzunluğunu belirle