Какие типы индексов существуют в Postgres?
Что проверяют
Знаете ли вы, что кроме B-tree в Postgres есть ещё пять встроенных типов, и умеете ли выбирать под запрос, а не перечислять список. Следом почти всегда просят подобрать индекс под конкретное условие: поиск по подстроке, по ключу в jsonb, по диапазону дат в таблице на сотни миллионов строк.
Как отвечать
Пройдите по типам, сразу называя задачу:
- B-tree: тип по умолчанию. Равенство, диапазоны, сортировка, уникальность, префиксный
LIKE 'abc%'. Умеет дедупликацию повторяющихся ключей; - Hash: только равенство, зато компактнее на длинных значениях. Пишется в WAL и реплицируется начиная с версии 10, так что совет «не берите, он не переживёт сбой» устарел лет на десять;
- GIN: когда в одном значении много элементов. Массивы,
jsonb, полнотекстовый поиск поtsvector, поиск по подстроке черезpg_trgm. Запись дороже, частично лечитсяfastupdate; - GiST: диапазоны, геометрия и PostGIS, ограничения
EXCLUDE, поиск ближайших соседей; - SP-GiST: несбалансированные структуры, например разбор текста по префиксу или IP-сети;
- BRIN: крошечный индекс для больших таблиц, где физический порядок строк совпадает с порядком значений, классика это колонка со временем вставки.
Дальше важнее самих типов: составные индексы и порядок колонок в них, частичные индексы с WHERE is_active, индексы по выражению для lower(email), INCLUDE ради index-only scan, построение через CREATE INDEX CONCURRENTLY на живой таблице. Если работали с эмбеддингами, упомяните pgvector с HNSW.
Где спотыкаются
Перечисляют типы и не могут выбрать под конкретный запрос. Интервьюеру нужен именно выбор с обоснованием.
Забывают, что индекс замедляет запись и занимает место, а на маленькой таблице или при низкой селективности планировщик его просто не возьмёт.
Ждут, что LIKE '%слово%' или WHERE lower(email) = ... попадут в обычный B-tree. Первому нужен триграммный GIN, второму индекс по выражению.