Co to jest kardynalność indeksu?

Autor: Opublikowano

W skrócie: Kardynalność indeksu to liczba różnych wartości klucza zapisanych w indeksie, często prezentowana przez bazę danych jako oszacowanie. Pomaga optymalizatorowi ocenić, ile wierszy może pasować do warunku zapytania i czy opłaca się użyć indeksu. Wysoka kardynalność zwykle sprzyja wyszukiwaniu konkretnych rekordów, ale sama nie gwarantuje szybszego działania.

Co dokładnie oznacza kardynalność indeksu

Indeks to dodatkowa struktura danych, która ułatwia odnajdywanie wierszy bez przeglądania całej tabeli. Jego klucz stanowi wartość jednej kolumny albo zestaw wartości kilku kolumn. Kardynalność opisuje, ile różnych takich kluczy występuje w danych, a nie ile łącznie wpisów zawiera indeks.

Załóżmy, że tabela klienci ma 100 000 wierszy. Jeśli każdy klient ma inny identyfikator, kardynalność indeksu na kolumnie id wynosi 100 000. Jeśli kolumna status zawiera tylko wartości aktywny, nieaktywny i zablokowany, jej kardynalność wynosi 3.

W narzędziach administracyjnych widoczna liczba nie zawsze jest dokładnym wynikiem zliczenia danych. Silnik może wyznaczać ją na podstawie próbki i przechowywać w statystykach, czyli informacjach o zawartości tabel używanych do planowania zapytań. Interpretację wartości NULL oraz szczegóły prezentacji kardynalności należy sprawdzić w dokumentacji konkretnego silnika.

Kardynalność a selektywność zapytania

Kardynalność jest cechą danych w indeksie. Selektywność warunku opisuje natomiast, jak mocno dany warunek ogranicza zbiór wyników. W praktyce warunek wybierający niewielką część tabeli nazywa się wysoce selektywnym; przy porównywaniu liczbowych wskaźników trzeba sprawdzić ich definicję, ponieważ stosowane konwencje bywają różne.

Dla wyszukania jednego unikalnego identyfikatora baza może znaleźć pojedynczy wiersz. Dla warunku status = 'aktywny' może potrzebować tysięcy lub dziesiątek tysięcy wierszy. W drugim przypadku odczyt indeksu, a następnie pobieranie rekordów z tabeli, może kosztować więcej niż jej pełne przeskanowanie.

Sama liczba różnych wartości nie mówi jednak, jak często występuje każda z nich. Jeśli 99 000 klientów jest aktywnych, a tylko 20 zablokowanych, dwa warunki na tej samej kolumnie mogą mieć zupełnie inną przydatność dla indeksu. Kardynalność wynosi nadal 3, ale rozkład danych jest nierówny.

Z tego powodu optymalizator — część silnika wybierająca sposób wykonania zapytania — może korzystać również z innych statystyk, na przykład histogramów opisujących rozkład wartości. Ich dostępność i sposób wykorzystania zależą od bazy danych.

Jak rozumieć kardynalność indeksu złożonego

Indeks złożony obejmuje więcej niż jedną kolumnę. Dla indeksu na (kraj, miasto) znaczenie ma liczba różnych par, a nie tylko liczba krajów czy miast rozpatrywanych osobno.

Przykładowo tabela może zawierać 10 krajów i 500 różnych par kraj–miasto. Kardynalność pierwszej części klucza wynosi wtedy 10, a całego klucza 500. Nie należy automatycznie mnożyć liczby różnych krajów przez liczbę różnych miast, ponieważ nie każda możliwa kombinacja musi występować w tabeli.

Niektóre narzędzia pokazują osobne oszacowania dla kolejnych początkowych części indeksu. W MySQL pole Cardinality w wyniku SHOW INDEX należy interpretować wraz z pozycją kolumny określoną przez Seq_in_index: oszacowanie dotyczy prefiksu indeksu kończącego się na tej pozycji.

Kolejność kolumn również wpływa na zastosowanie indeksu. Dla typowego indeksu B-tree, czyli indeksu o uporządkowanej strukturze drzewiastej, (kraj, miasto) naturalnie wspiera wyszukiwanie po kraju oraz po kraju i mieście. Wyszukiwanie wyłącznie po mieście może wymagać innego sposobu dostępu; dostępne optymalizacje zależą od silnika.

Dlaczego wysoka kardynalność nie wystarcza

Indeks na niemal unikalnej kolumnie może być dobrym wyborem dla porównania z konkretną wartością, ale mniej przydatnym dla szerokiego zakresu. Zapytanie pobierające większość rekordów według daty może nie skorzystać z indeksu, mimo że daty mają wiele różnych wartości.

Znaczenie ma też sposób zapisania warunku. Zastosowanie funkcji do indeksowanej kolumny, na przykład przekształcenie daty do samego roku, może utrudnić wykorzystanie zwykłego indeksu. Możliwość użycia indeksu funkcyjnego lub odpowiedniego przepisania zapytania trzeba sprawdzić dla danego silnika.

Indeks może ponadto pomagać w sortowaniu, łączeniu tabel albo odczycie danych bez sięgania do tabeli, jeśli zawiera wszystkie potrzebne kolumny. Dlatego niska kardynalność nie jest sama w sobie powodem do usunięcia indeksu. Trzeba też uwzględnić jego koszt: zajęte miejsce oraz dodatkową pracę przy zapisie i aktualizacji danych.

Jak sprawdzić, czy indeks pomaga

Oceniaj indeks na podstawie rzeczywistego zapytania, a nie samej liczby w panelu administracyjnym:

  1. Wybierz typowe zapytanie i reprezentatywne wartości parametrów, także wartości częste i rzadkie.
  2. Sprawdź plan wykonania za pomocą EXPLAIN lub odpowiednika w swoim silniku.
  3. Zwróć uwagę na wybrany indeks, szacowaną liczbę wierszy i sposób dostępu do tabeli.
  4. Jeśli to bezpieczne, porównaj oszacowania z rzeczywistym wykonaniem. Pamiętaj, że polecenia analizujące wykonanie mogą uruchamiać zapytanie.
  5. Przy dużych rozbieżnościach sprawdź aktualność statystyk i zasady ich odświeżania w dokumentacji bazy.

Po masowym imporcie, usuwaniu rekordów lub zmianie rozkładu wartości statystyki mogą nie odzwierciedlać aktualnych danych. Zanim dodasz kolejny indeks, sprawdź plan problematycznego zapytania i stan statystyk — to pozwoli odróżnić brak odpowiedniego indeksu od błędnego oszacowania kosztów.

Zobacz też: Co to jest FireFox?

Przeczytaj także

Dowiedz się, jak PHP-FPM obsługuje żądania PHP, czym różni się od serwera WWW i jak dobrać ustawienia procesów do ruchu oraz zasobów hostingu.
Poznaj BIND, otwarte oprogramowanie serwera DNS: sprawdź, jak obsługuje domeny, czym różnią się jego role i kiedy warto samodzielnie go wdrożyć.
Poznaj najważniejsze Security Headers, ich rolę w ochronie strony oraz sposób sprawdzania i wdrażania nagłówków bez blokowania potrzebnych funkcji.