ENIGMA AI
ENIGMA AI

Расскажите про индексы в базах данных.

встречается 2× middle database

Как ответить

Индексы в базах данных — это вспомогательные структуры, которые ускоряют операции поиска, фильтрации и сортировки. По сути это копия части данных, упорядоченная для быстрого доступа. За это приходится платить дополнительным местом на диске и замедлением записей, потому что индекс нужно обновлять при каждом INSERT, UPDATE или DELETE.

Самый распространённый тип — B-tree (или его вариация B+ tree). Работает для равенства (=) и диапазонов (<, >, BETWEEN). Например, поиск пользователя по email:

CREATE INDEX idx_users_email ON users(email);
SELECT * FROM users WHERE email = 'test@example.com';

Без индекса база будет делать полное сканирование таблицы — читать все строки. С индексом поиск идёт по дереву, сложность O(log N), а не O(N). Для миллиона записей это разница в сотни раз.

Есть и другие типы:

  • Hash-индекс — только для точного сравнения, очень быстрый, но не поддерживает диапазоны. Используется редко, например в PostgreSQL при явном указании.
  • GiST и GIN — для полнотекстового поиска, JSONB, массивов. В PostgreSQL GIN хорошо работает с jsonb и tsvector.
  • Full-text — отдельный тип для текстового поиска, но чаще это функциональные индексы с to_tsvector.

На практике чаще всего работаешь с B-tree. Важно понимать композитные индексы — на несколько колонок. Порядок колонок имеет значение: индекс на (a, b) эффективен для фильтрации по a, по a и b вместе, для ORDER BY a, b, но не для фильтрации только по b. Если часто делаешь запросы с WHERE b = ? и WHERE a = ?, лучше создать два отдельных индекса.

Ещё одна оптимизация — covering index (индекс с покрытием), когда все нужные колонки запроса есть в самом индексе. Тогда база может вообще не обращаться к таблице — только к индексу. Это видно в EXPLAIN ANALYZE как «Index Only Scan».

Не стоит ставить индексы на всё подряд. На маленьких таблицах (до нескольких тысяч строк) полное сканирование может быть быстрее из-за накладных расходов. На колонках с низкой селективностью (пол, статус на два значения) индекс почти не поможет, потому что база всё равно прочитает много строк. И на таблицах с очень частыми вставками каждый лишний индекс снижает производительность.

Иногда индексы нужно обслуживать: в PostgreSQL есть REINDEX для устранения фрагментации, в MySQL — OPTIMIZE TABLE. План запроса — основной инструмент для проверки, используются ли индексы. EXPLAIN (ANALYZE, BUFFERS) показал, что запрос читает все строки? Значит, нужен индекс.

Ключевые тезисы

  • Индексы ускоряют поиск/фильтрацию за счёт дополнительных структур данных (B-tree, hash, GIN), но замедляют запись.
  • B-tree — универсальный тип для равенства и диапазонов. Работает за O(log N).
  • Композитные индексы с правильным порядком колонок критичны для многоусловных запросов.
  • Covering index позволяет получать данные только из индекса без обращения к таблице (Index Only Scan).
  • Нельзя индексировать всё: на маленьких таблицах или колонках с низкой селективностью индексы бесполезны и вредят производительности записи.

Что спросят дальше

  • — Как вы выберете, какие колонки включить в композитный индекс? Приведите пример с WHERE и ORDER BY.
  • — Как работает Index Only Scan и что может помешать его использованию?
  • — В чём разница между кластеризованным и некластеризованным индексом? Для каких сценариев подходит каждый?

Готовьтесь к собеседованию с ENIGMA AI

AI-суфлёр подсказывает ответы прямо на собеседовании в реальном времени — незаметно для интервьюера.

Скачать приложение