Gymterview
middle

Какие типы индексов существуют?

Типы индексов определяются их внутренней структурой, влиянием на физическое расположение данных и областью применения. Классификация многомерна: один и тот же индекс можно описать по нескольким категориям одновременно.

По структуре данных

Тип Описание Подходит для
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 типов без понимания, когда какой применять.