Как ответить
Если говорить коротко, то индексы в базах данных — это структуры, которые ускоряют поиск строк при выборке, но замедляют запись и занимают место. Главное различие между типами — как они организованы и какие операции умеют эффективно выполнять.
Самый распространённый тип — B-Tree (B+дерево). Используется по умолчанию в PostgreSQL, MySQL (InnoDB), Oracle. Подходит для точечных запросов (WHERE id = 42), диапазонов (WHERE price BETWEEN 100 AND 200), сортировок (ORDER BY) и операций с префиксом (LIKE 'abc%'). Работает логарифмически: глубина дерева растёт медленно. Реальный пример: поиск заказа по номеру из миллиона — обычно 2-3 чтения страницы.
Hash-индекс — экзотика. Используется только для точных сравнений (WHERE id = 42). Никаких диапазонов, сортировок или LIKE. Время поиска — O(1) в среднем. В реляционных БД почти не встречается в базовой поставке, кроме Memory-таблиц MySQL и hash-индексов PostgreSQL через расширение hash. На практике — быстрее B-Tree только на вставках при уникальных значениях, но стоит редко.
GiST (Generalized Search Tree) — для нестандартных типов данных. Используется для полнотекстового поиска, геоданных (например, поиск точек в радиусе от координаты), массивов, интервалов временных рядов. От B-Tree отличается тем, что не требует строгого линейного порядка. Типичный пример: найти все рестораны в радиусе 5 км от точки (55.7558, 37.6176) — GiST справится, B-Tree — нет.
GIN (Generalized Inverted Index) — инвертированный индекс. Идеален для поиска вхождений значения внутри составного поля: массивы (WHERE tags @> ARRAY['tech']), JSONB (WHERE data @> '{"key": "value"}'), полнотекстовый поиск (tsvector). Работает медленнее B-Tree на вставках, но даёт скорость поиска по подмножествам элементов.
Ещё стоит упомянуть BRIN (Block Range Index) — для очень больших таблиц, где данные физически упорядочены. Например, лог событий с timestamp: если записи пишутся по времени, BRIN может сократить количество просматриваемых страниц в десять раз при сканировании диапазона дат. Занимает сильно меньше места, чем B-Tree, но менее точен: нужно подбирать параметр pages_per_range.
На практике в PostgreSQL 90% индексов — B-Tree. GiST и GIN — под специфические задачи: гео, JSON, полнотекст. Hash и BRIN — для узких ниш. Важно помнить: лишний индекс — это лишняя запись при INSERT/UPDATE и лишний объём на диске.