Indeks pełnotekstowy

Specjalny indeks do szybkiego przeszukiwania treści tekstowej po słowach i frazach. Stosowany w wyszukiwarkach i polach z długim tekstem.

Indeks pełnotekstowy (ang. full-text index) to specjalny rodzaj indeksu w bazie danych, który przyspiesza wyszukiwanie po słowach i frazach wewnątrz długich pól tekstowych. W przeciwieństwie do zwykłego indeksu, który dobrze radzi sobie z dopasowaniem od początku wartości (np. WHERE nazwa = 'Anna' albo LIKE 'Ann%'), indeks pełnotekstowy rozumie treść jako zbiór wyrazów i pozwala znaleźć rekord zawierający dane słowo gdziekolwiek w tekście — bez skanowania całej tabeli.

Jak to działa i do czego służy

Pod spodem silnik tworzy tzw. inverted index (indeks odwrócony): rozbija tekst na pojedyncze tokeny (słowa), a potem trzyma mapę „słowo → lista dokumentów, w których występuje”. Dzięki temu zapytanie o frazę nie przegląda każdego wiersza po kolei, tylko od razu sięga do listy pasujących rekordów. Po drodze często dochodzi normalizacja: usuwanie tzw. stop words (np. „i”, „the”), sprowadzanie odmian do rdzenia (stemming) i ignorowanie wielkości liter.

Stosuje się to wszędzie tam, gdzie masz dużo tekstu i ludzi, którzy chcą go przeszukiwać naturalnie: wyszukiwarka na blogu, przeszukiwanie opisów produktów w sklepie, panel wsparcia z tysiącami zgłoszeń, dokumentacja. Bonusem bywa relevance ranking — wyniki da się posortować według trafności, a nie tylko „pasuje / nie pasuje”.

Przykład z praktyki

W MySQL/MariaDB zakładasz taki indeks na kolumnie i odpytujesz go specjalną składnią:

  • ALTER TABLE artykuly ADD FULLTEXT INDEX ft_tresc (tytul, tresc);
  • SELECT * FROM artykuly WHERE MATCH(tytul, tresc) AGAINST('indeks pełnotekstowy' IN NATURAL LANGUAGE MODE);

W PostgreSQL działa to przez typy tsvector i tsquery oraz indeks GIN, a gdy potrzebujesz czegoś poważniejszego (literówki, wielojęzyczność, agregacje), sięgasz po dedykowany silnik jak Elasticsearch albo OpenSearch — one są zbudowane wokół indeksu pełnotekstowego od podstaw.

Na co uważać

  • To nie to samo co LIKE '%słowo%' — taki LIKE z gwiazdką na początku w ogóle nie korzysta z indeksu i przy większej tabeli zatka serwer.
  • Domyślna długość słowa. W MySQL (InnoDB) krótkie słowa, np. trzyliterowe, bywają pomijane przez ustawienie innodb_ft_min_token_size. Szukasz „SQL” i nic nie znajdujesz? Sprawdź konfigurację.
  • Język ma znaczenie. Stemming i stop words są zależne od języka — domyślne reguły dla angielskiego potrafią słabo działać na polskich odmianach.
  • Indeks zajmuje miejsce i kosztuje przy zapisie. Każdy INSERT/UPDATE musi go zaktualizować, więc nie zakładaj go na ślepo na wszystkim.

Pojęcia powiązane: inverted index, tokenizacja, stemming, stop words, indeks GIN, tsvector, Elasticsearch, relevance ranking, zwykły indeks B-tree.