Типы индексов определяются их внутренней структурой, влиянием на физическое расположение данных и областью применения. Классификация многомерна: один и тот же индекс можно описать по нескольким категориям одновременно.
По структуре данных
| Тип |
Описание |
Подходит для |
| B-tree (B+tree) |
Сбалансированное дерево, самый распространённый |
Равенство, диапазоны, сортировка |
| Hash |
Хранит хэши значений, поиск за O(1) |
Только точное равенство (=) |
| GiST |
Обобщённое дерево поиска |
Геоданные, полнотекстовый поиск |
| GIN (инвертированный) |
Словарь слов с указателями на документы |
Полнотекстовый поиск, JSONB, массивы |
| BRIN |
Хранит диапазоны значений для блоков страниц |
Большие таблицы с естественной сортировкой |
По воздействию на физическое расположение данных
| Тип |
Описание |
| Кластерный |
Данные физически упорядочены по индексу. Один на таблицу |
| Некластерный |
Отдельная структура со ссылками на строки. Может быть много |
По количеству столбцов
| Тип |
Описание |
Пример |
| Простой |
По одному столбцу |
CREATE INDEX idx ON t(col1) |
| Составной (композитный) |
По нескольким столбцам, порядок важен |
CREATE INDEX idx ON t(col1, col2) |
| С включёнными столбцами |
Ключевые + неключевые столбцы (covering index) |
CREATE INDEX idx ON t(col1) INCLUDE (col2) |
По содержимому
| Тип |
Описание |
| Уникальный |
Все значения уникальны |
| Частичный (partial) |
Индексирует только строки, удовлетворяющие условию |
| Функциональный |
Построен по результату выражения или функции |
| Полнотекстовый |
Оптимизирован для поиска по тексту |
| Пространственный |
Оптимизирован для геоданных (координаты) |
| Битовый (bitmap) |
Битовая карта для каждого значения, эффективен при низкой кардинальности |
| Обратный (reverse) |
B-tree с реверсированным ключом, снимает конкуренцию за последний блок при автоинкременте |
По покрытию данных
| Тип |
Описание |
| Полный |
Покрывает все строки таблицы |
| Частичный (partial) |
Покрывает подмножество строк по условию |
| Покрывающий (covering) |
Содержит все столбцы, нужные запросу (Index Only Scan) |
Примеры создания
Примеры создания различных индексов (PostgreSQL)
-- B-tree (по умолчанию)
CREATE INDEX idx_users_email ON users(email);
-- Уникальный
CREATE UNIQUE INDEX idx_users_email_uniq ON users(email);
-- Составной
CREATE INDEX idx_orders_user_date ON orders(user_id, created_at);
-- Частичный (только активные)
CREATE INDEX idx_users_active ON users(email) WHERE active = true;
-- Функциональный (поиск без учёта регистра)
CREATE INDEX idx_users_lower_email ON users(LOWER(email));
-- GIN для JSONB
CREATE INDEX idx_data_gin ON documents USING GIN(data);
-- Покрывающий (INCLUDE)
CREATE INDEX idx_orders_covering ON orders(user_id) INCLUDE (total, status);
-- Hash (только для равенства)
CREATE INDEX idx_sessions_token ON sessions USING HASH(token);
На собеседовании: достаточно знать B-tree, Hash, GIN, уметь объяснить кластерный vs некластерный, и понимать разницу между составным и покрывающим индексом. Частая ошибка — перечислить 20 типов без понимания, когда какой применять.