← Wszystkie artykuły

Indeksy w bazach danych: jak przyspieszają zapytania

Burncode Team 3 minuty czytania

Ogromna część problemów w stylu „dlaczego nasza baza danych jest taka wolna” sprowadza się do jednego brakującego elementu: indeksu. To jedna z tych rzeczy, których zrozumienie daje najwięcej korzyści przy pracy z bazami danych – i jest prostsza, niż sugeruje większość wyjaśnień.

Analogia z biblioteką

Wyobraźcie sobie bibliotekę bez katalogu i bez żadnego systemu porządkowania – każda książka stoi tam, gdzie akurat znalazło się miejsce na półce. Znalezienie konkretnego tytułu oznacza przejście wszystkich alejek i sprawdzenie każdej książki po kolei. Tak właśnie wygląda tabela bez indeksu: aby znaleźć wiersz, baza danych sprawdza wszystkie wiersze, jeden po drugim, aż trafi na właściwy. Nazywa się to pełnym skanowaniem tabeli (full table scan) i przy małej tabeli nie stanowi problemu – ale przy tabeli z milionami wierszy jest bezlitośnie wolne.

Indeks to właśnie katalog biblioteczny. To osobna, uporządkowana struktura, która mówi: „wiersze, w których ta kolumna ma tę wartość, znajdują się dokładnie tutaj”, dzięki czemu baza danych może przejść od razu we właściwe miejsce, zamiast sprawdzać wszystko.

Jak to działa pod maską

Większość baz danych implementuje indeksy za pomocą struktury danych zwanej B-drzewem – zrównoważonego drzewa, które przechowuje wartości w uporządkowany sposób i pozwala bazie zawężać wyszukiwanie, z grubsza o połowę pozostałych możliwości na każdym kroku, podobnie jak szuka się słowa w papierowym słowniku. Zamiast sprawdzać milion wierszy po kolei, baza danych może sprawdzić kilkanaście węzłów drzewa i trafić prosto w odpowiedź.

Dlatego dodanie właściwego indeksu potrafi zamienić zapytanie trwające kilka sekund w takie, które zajmuje kilka milisekund. Nie każecie bazie danych pracować ciężej – dajecie jej znacznie krótszą drogę do tej samej odpowiedzi.

Co właściwie indeksować

  • Kolumny używane w klauzulach WHERE – wszystko, po czym często filtrujecie, to mocny kandydat do indeksu.
  • Klucze obce – kolumny odwołujące się do innej tabeli, bo złączenia mocno na nich polegają.
  • Kolumny używane w ORDER BY – indeks, który już przechowuje dane we właściwej kolejności, pozwala całkowicie pominąć etap sortowania.
  • Kolumny w warunkach JOIN – złączanie dużych tabel bez indeksów na kolumnach złączenia to jedna z najczęstszych przyczyn wolnych zapytań.

Kompromis, o którym nikt nie mówi, dopóki nie zaboli

Indeksy nie są za darmo. Każdy indeks trzeba aktualizować przy każdym wstawieniu, modyfikacji lub usunięciu wiersza, co oznacza, że im więcej indeksów, tym wolniejsze operacje zapisu. Zajmują też realne miejsce na dysku, co przy dużej skali ma znaczenie. Błędem nie jest abstrakcyjne „za mało” czy „za dużo indeksów”, tylko indeksowanie kolumn, po które zapytania prawie nigdy nie sięgają – to spowalnia każdy zapis w zamian za korzyść, której nigdy nie odbierzecie.

Dobra praktyczna zasada: indeksujcie kolumny, po których wasze rzeczywiste zapytania filtrują, złączają i sortują – zajrzyjcie do logu wolnych zapytań, jeśli go macie – i nie ulegajcie pokusie indeksowania wszystkiego „na wszelki wypadek”.

Ustalenie, których indeksów naprawdę potrzebuje produkcyjna baza danych – a które po cichu obciążają każdy zapis – to rutynowa część naszej pracy nad infrastrukturą. Często jest to też pojedyncza zmiana o największym wpływie na system, który zaczął zwalniać pod realnym ruchem.