Какой тип индекса выбрать в PostgreSQL?
Индексы — мощный инструмент для ускорения запросов, но не все они одинаково полезны. В PostgreSQL есть несколько типов индексов, и вот как не промахнуться с выбором:
B-tree (по умолчанию)
Лучший выбор для: =, <, >, BETWEEN, ORDER BY.
Поддерживает сортировку.
Используется в 90% случаев.
Hash
Только для точного сравнения =.
Не поддерживает диапазоны, сортировку, LIKE.
Редко используется, но может быть быстрее B-tree на =.
GIN (Generalized Inverted Index)
Для массивов, jsonb, full-text search.
Отличен при поиске по вложенным структурам или множеству значений.
GiST (Generalized Search Tree)
Для геоданных (PostGIS), поиска по диапазонам, tsvector.
Более универсален, но медленнее в некоторых кейсах, чем GIN.
BRIN (Block Range Index)
Для огромных таблиц, где данные физически упорядочены.
Занимает очень мало места.
Не всегда эффективен — зависит от корреляции данных.
Не кидайтесь ставить индекс "на всякий случай". Подбирай тип под паттерн запроса и тип данных.
Индексы — мощный инструмент для ускорения запросов, но не все они одинаково полезны. В PostgreSQL есть несколько типов индексов, и вот как не промахнуться с выбором:
B-tree (по умолчанию)
Лучший выбор для: =, <, >, BETWEEN, ORDER BY.
Поддерживает сортировку.
Используется в 90% случаев.
SQL:
CREATE INDEX idx_users_name ON users(name);
Hash
Только для точного сравнения =.
Не поддерживает диапазоны, сортировку, LIKE.
Редко используется, но может быть быстрее B-tree на =.
SQL:
CREATE INDEX idx_users_email_hash ON users USING hash(email);
GIN (Generalized Inverted Index)
Для массивов, jsonb, full-text search.
Отличен при поиске по вложенным структурам или множеству значений.
SQL:
CREATE INDEX idx_data_tags ON posts USING gin(tags);
GiST (Generalized Search Tree)
Для геоданных (PostGIS), поиска по диапазонам, tsvector.
Более универсален, но медленнее в некоторых кейсах, чем GIN.
SQL:
CREATE INDEX idx_events_location ON events USING gist(location);
BRIN (Block Range Index)
Для огромных таблиц, где данные физически упорядочены.
Занимает очень мало места.
Не всегда эффективен — зависит от корреляции данных.
SQL:
CREATE INDEX idx_logs_timestamp ON logs USING brin(timestamp);
Не кидайтесь ставить индекс "на всякий случай". Подбирай тип под паттерн запроса и тип данных.