DBAtlas · Veritabanı operasyon atlası

Karar: Hangi index türü?

Doğru index türü; sorgunun erişim biçimine (eşitlik mi, aralık mı, metin/JSON araması mı), kolonun kardinalitesine ve okuma/yazma dengesine bağlıdır. Yanlış index hem yeri boşa harcar hem yazmayı yavaşlatır. Bu ağaç, sorgu şeklinden başlayarak B-tree, Hash, Bitmap, GIN/GiST, kısmi (partial) ve kapsayan (covering) index seçenekleri arasında yönlendirir ve bileşik index'te kolon sırasının kritik olduğunu hatırlatır.

Sorgun bu kolonu nasıl kullanıyor?

Index seçiminde en belirleyici şey erişim biçimidir. Kolonda sadece '=' ile mi eşleşiyorsun, aralık/sıralama (>, <, BETWEEN, ORDER BY) mı yapıyorsun, yoksa tam metin, JSON alanı veya geometrik/dizilerde mi arıyorsun? Buradan başla; ihtiyaç netleşmeden index türü seçilmez.

  • Eşitlik ve aralık/sıralama karışık (=, >, <, BETWEEN, ORDER BY)
  • Yalnızca eşitlik (=), aralık veya sıralama yok
  • Tam metin, JSON/JSONB alanı, dizi veya geometrik arama
  • Sorgu hep aynı küçük satır alt kümesine bakıyor (ör. WHERE durum='aktif')

Kolonun kardinalitesi (farklı değer sayısı) nasıl?

Aralık/sıralama gerekiyorsa varsayılan B-tree'dir; ancak çok az sayıda farklı değer içeren (düşük kardinalite: cinsiyet, durum, evet/hayır) kolonlarda ve ağırlıklı okuma yapılan veri ambarında Bitmap index daha iyi olabilir. Kolonda çok sayıda benzersiz değer mi var, yoksa az sayıda tekrar eden değer mi?

  • Yüksek kardinalite (çok sayıda benzersiz değer) veya OLTP yük
  • Düşük kardinalite ve ağırlıklı okuma / veri ambarı (DWH)

Sorgu tablodan sadece index'teki kolonları mı okuyor?

Erişim biçimi B-tree'ye uygun. Son bir optimizasyon: sorgunun döndürdüğü ve filtrelediği tüm kolonlar index'te bulunursa, motor tabloya hiç gitmeden yalnızca index'ten cevap verebilir (index-only / covering scan). Sorgun az sayıda kolon mu okuyor, yoksa satırın büyük kısmına mı ihtiyaç duyuyor?

  • Evet, birkaç kolon; tabloya gitmeden cevaplanabilir
  • Hayır, standart erişim yeterli

Öneri: B-tree (varsayılan)

B-tree dengeli bir ağaç yapısıdır ve eşitlik, aralık, sıralama (ORDER BY), ön ek (prefix) ile LIKE 'abc%' ve MIN/MAX gibi geniş bir erişim yelpazesini destekler. Çoğu ilişkisel motorda varsayılan index türüdür ve emin olmadığında doğru başlangıçtır.

Öneri: Hash index (yalnız eşitlik)

Hash index, kolon değerinin hash'ini saklar ve yalnızca tam eşitlik ('=') aramalarında çok hızlıdır. Aralık, sıralama veya ön ek aramalarını desteklemez; bu yüzden dar bir kullanım alanı vardır.

Öneri: Bitmap index (düşük kardinalite / DWH)

Bitmap index, her farklı değer için bir bit dizisi tutar ve birden çok düşük kardinaliteli koşulu bit AND/OR ile çok hızlı birleştirir. Veri ambarı ve raporlama gibi ağırlıklı okuma yapılan iş yüklerinde güçlüdür.

Öneri: GIN / GiST (metin, JSON, dizi, geometri)

PostgreSQL'de standart B-tree'nin çözemediği erişim tipleri için özel index aileleri vardır. GIN, bir değerin içindeki birçok bileşeni (kelimeler, JSONB anahtarları, dizi elemanları) işaret eder; GiST ise geometrik/aralık/en yakın komşu (nearest-neighbor) gibi sorgulara uygundur.

Öneri: Kısmi / filtrelenmiş (partial) index

Kısmi index, tablonun tamamı yerine yalnızca bir koşulu (WHERE ...) sağlayan satırları indeksler. Sorgular hep aynı küçük alt kümeye bakıyorsa index çok küçülür, hızlanır ve yazma maliyeti azalır.

Öneri: Kapsayan (covering / INCLUDE) index

Kapsayan index, sorgunun ihtiyaç duyduğu tüm kolonları index'te barındırarak motorun tabloya (heap) hiç gitmeden yalnızca index'ten cevap vermesini sağlar (index-only scan). Sık çalışan, az kolon döndüren sorgularda ciddi hızlanma verir.

DBAtlas'ta aç →