Indeks klastrowany

Indeks określający fizyczny porządek przechowywania wierszy w tabeli. Tabela może mieć tylko jeden taki indeks, zwykle na kluczu głównym.

Indeks klastrowany (ang. clustered index) to indeks, który narzuca fizyczny porządek przechowywania wierszy w tabeli. Inaczej mówiąc: dane na dysku są poukładane dokładnie w kolejności klucza tego indeksu. Dlatego tabela może mieć tylko jeden indeks klastrowany — wiersze fizycznie da się ułożyć tylko na jeden sposób. Najczęściej zakłada się go na kluczu głównym (PRIMARY KEY), bo większość silników robi to automatycznie.

Jak to działa

W praktyce indeks klastrowany to nie jakaś osobna struktura obok tabeli — to jest tabela. Liście drzewa B-tree (a właściwie B+ tree) zawierają kompletne wiersze danych, a nie wskaźniki do nich. Gdy szukasz rekordu po kluczu klastrowanym, silnik schodzi po drzewie i od razu trafia na komplet kolumn — bez dodatkowego skoku. To czyni go szybkim do wyszukiwań po zakresie (WHERE id BETWEEN 100 AND 200), bo sąsiednie wartości leżą obok siebie.

Dla porównania indeks nieklastrowany trzyma tylko klucz i odniesienie do wiersza. Żeby pobrać resztę kolumn, musi wykonać dodatkowe sięgnięcie do indeksu klastrowanego — w SQL Server nazywa się to Key Lookup i potrafi sporządnie spowolnić zapytanie.

Przykład z praktyki

W MS SQL Server tworzysz go jawnie:

CREATE CLUSTERED INDEX IX_Orders_Date ON Orders(OrderDate);

W MySQL/InnoDB nie masz nawet takiego wyboru — silnik zawsze robi indeks klastrowany. Jeśli zdefiniujesz PRIMARY KEY, to on nim zostaje. Jeśli nie, InnoDB użyje pierwszego unikalnego NOT NULL, a w ostateczności stworzy ukryty 6-bajtowy klucz (GEN_CLUST_INDEX), którego i tak nie zobaczysz.

Na co uważać

  • Szeroki klucz boli podwójnie. W InnoDB każdy indeks nieklastrowany przechowuje wartość klucza klastrowanego jako wskaźnik. Klucz na UUID typu CHAR(36) rozdmuchuje wszystkie pozostałe indeksy.
  • Losowe klucze = fragmentacja. Wstawianie rekordów z losowym UUID jako kluczem klastrowanym powoduje rozrzucanie wierszy po całej strukturze i page splity. Klucz rosnący (AUTO_INCREMENT, BIGINT IDENTITY) dopisuje na końcu i jest dużo zdrowszy.
  • Mit „PK to zawsze indeks klastrowany”. Nie zawsze — w SQL Server możesz mieć PK nieklastrowany, a klaster założyć na innej kolumnie.

Pojęcia powiązane: indeks nieklastrowany, klucz główny (PRIMARY KEY), B-tree / B+ tree, heap (tabela bez indeksu klastrowanego), Key Lookup, covering index, fragmentacja indeksów.