Базы данных

Как работает индексирование баз данных: принципы

Разбираем, как работает индексирование баз данных: B-дерево, хэш, bitmap. Почему индексы в БД ускоряют запросы, типы индексов, компромиссы записи и оптимизация SQL-запросов для больших данных.

Как работает индексирование баз данных?

Учитывая, насколько важна индексация по мере роста набора данных, может кто-нибудь объяснить, как работает индексирование на уровне, независимом от конкретной СУБД?

Индексирование баз данных работает как справочник в книге: создает отдельную структуру данных, которая быстро указывает, где именно на диске лежат нужные строки таблицы, без полного сканирования всех записей. По мере роста объема данных — от тысяч до миллионов строк — индексы в БД превращают медленный поиск в молниеносный, используя деревья вроде B-дерева или хэш-таблицы. Но это не бесплатно: каждый INSERT, UPDATE или DELETE требует обновления индекса, так что индексы в БД — это баланс между скоростью чтения и нагрузкой на запись.


Содержание


Что такое индекс в базе данных

Представьте огромную таблицу с миллионами строк — клиенты, заказы, логи. Без индекса как работают индексы в БД сводится к полному сканированию: СУБД читает каждую строку по порядку, проверяя условие WHERE. Это как искать иголку в стоге сена, листая весь стог.

Индекс меняет всё. Это отдельная структура, привязанная к одному или нескольким столбцам таблицы. Она хранит значения этих столбцов плюс указатели на реальные строки данных (обычно — адреса страниц на диске). Habr объясняет просто: индекс сопоставляет значение (например, “Иванов”) с местоположением строки, где этот Иванов сидит. Не нужно рыться везде — бац, и ты на месте.

А почему это критично при росте данных? Маленькая таблица (пару тысяч строк) сканируется за секунды. Но при миллионах? Минуты или часы. Индексация — ключ к масштабированию, независимо от СУБД вроде PostgreSQL или MySQL.


Почему индексы ускоряют запросы

Суть в экономии I/O-операций. Диски медленные, память быстрая. Таблицы хранятся блоками (страницами, обычно 4-16 КБ). Полное сканирование — это чтение тысяч страниц. Индекс? Читаешь крошечный кусок индекса и прыгаешь прямо к цели.

Возьмем аналогию с книгой, как в Software Cats: оглавление позволяет открыть нужную главу, не листая все 500 страниц. Или предметный указатель — ищешь “индексация”, видишь страницы 42, 156. В БД то же: индекс отсортирован, поиск по нему — O(log N), а не O(N).

При росте данных эффект экспоненциальный. 10 000 строк? Без индекса — 10 сек. С индексом — 0.01 сек. 1 млн строк? Без — часы, с — секунды. Википедия подчеркивает: базы слишком велики для памяти, индексы решают это, работая с блоками.

Но вопрос: а если данных мало? Не торопитесь индексировать всё подряд — overhead на обновления съест выгоду.


Как устроена структура индекса

Индексы не плоские списки. Основная структура — B-дерево (или B±дерево), универсальное для большинства СУБД. Это сбалансированное дерево: корень, узлы, листья.

В листьях — отсортированные ключи + указатели на данные. Узлы выше содержат минимакс-значения для быстрого спуска. Ищешь “Иванов”? Сравниваешь с корнем, спускаешься по ветке — 3-4 шага вместо миллионов сравнений.

Practicum Yandex рисует дерево: каждый узел — страница диска, минимизирует чтения. B±вариант круче: листья связаны списком для диапазонов (WHERE age BETWEEN 20 AND 30).

Хранение? Индекс — отдельный файл или сегменты. Ключи компактны, но растут с данными. Фантомные записи? Индексы их игнорируют, фокусируясь на поиске (как в Selectel).

Коротко: дерево балансируется автоматически, поиск логарифмический. Идеально для дисков.


Основные типы индексов в БД

Не все индексы — B-деревья. Выбор зависит от запросов. Вот ключевые типы индексов в БД:

B-дерево и B±дерево

Стандарт для равенств, диапазонов, сортировки. Поддерживает ORDER BY, GROUP BY. Минус — не для неравенств вроде LIKE ‘%text%’.

Хэш-индексы

Для точных равенств (WHERE id=123). Хэш-функция дает прямой доступ — O(1). Но диапазоны? Нет, не сортировано. Habr отмечает: супер для ключей, но редко.

Bitmap-индексы

Для низкой кардинальности (пол, статус: да/нет). Битовая карта: бит=1, если значение совпадает. Идеально для AND/OR в WHERE. Экономит место, но обновления дорогие.

GiST, GIN и полнотекстовые

GiST — для гео, массивов (пространственные запросы). GIN — для JSON, full-text search. Полнотекстовые — inverted index: слова → документы.

Timeweb предупреждает: B-дерево — 90% случаев, остальное под задачи.

Какой выбрать? Смотрите запросы.


Как СУБД использует индексы в запросах

СУБД планировщик (query planner) решает: индекс или скан? Анализирует статистику, селективность.

  • WHERE id=5: индекс-сканирование.
  • BETWEEN: range scan по B-дереву.
  • JOIN: индекс на join-колонке — nested loop или hash join.
  • ORDER BY: покрывающий индекс (covering) — все данные в индексе, таблицу не трогаем.

Merionet пример: первые N клиентов по алфавиту — индекс дает отсортированные страницы сразу.

Мультиколоночные (составные)? Порядок важен: сначала высокоселективный столбец. WHERE name=‘Иванов’ AND city=‘Москва’ — индекс (name,city), но не наоборот.


Компромиссы: скорость чтения против записи

Индексы ускоряют SELECT, но тормозят DML. INSERT? Вставка в дерево + балансировка. UPDATE ключевой колонки? Перестройка. DELETE — пометка + вакуум.

Software Cats советует: мониторьте. 10 индексов на таблицу? Запись в 10 раз медленнее.

Рост данных усиливает: больше обновлений — больше лагов. Решение: частичные индексы (только WHERE active=true), батчинг.

Баланс: читайте 80% времени? Индексируйте агрессивно. Пишете много? Меньше индексов.


Практика: когда и как создавать индексы

Анализируйте медленные запросы. Столбцы для индекса:

  • В WHERE, часто фильтруемые.
  • JOIN-колонки.
  • ORDER/GROUP BY.

Составные: 2-4 колонки, селективность сверху вниз. Покрывающие: включают все SELECT-поля.

Удаляйте неиспользуемые — жрут место (до 50% размера БД). WorkSolutions подчеркивает роль первичных ключей — они индексы по умолчанию.

При росте: начните с 1-2 индексов на hot-таблицы.


Инструменты для анализа и оптимизации

Оптимизация запросов без инструментов — лотерея. EXPLAIN/EXPLAIN ANALYZE покажет план: Index Scan? Seq Scan? Seq — плохо.

  • pg_stat_user_indexes (Postgres): использование.
  • SHOW INDEX (MySQL).
  • Use The Index, Luke — bible для понимания.

Мониторьте: если индекс не юзается — дропните. Статистику обновляйте регулярно.


Частые ошибки при работе с индексами

  • Индекс на низкой селективности (gender): бесполезно.
  • LIKE ‘%text’ — не использует B-дерево.
  • Слишком много индексов — БД тормозит на записи.
  • Забыть о сортировке в составных.
  • Не учитывать NULL — часто отдельно.

Bourabai: индекс упорядочен, но без плана — фигня.

Избегайте: тестируйте на реальных данных.


Источники

  1. Как устроено индексирование баз данных — Habr
  2. Зачем нужны индексы в базе данных — Software Cats
  3. Индекс (базы данных) — Википедия
  4. Индексы в SQL — TimeWeb Cloud
  5. Индексы в реляционной базе данных — Merionet Wiki
  6. Индексы в SQL — Practicum Yandex
  7. Индекс в PostgreSQL — Selectel
  8. Влияние индексов БД на производительность — WorkSolutions
  9. Индексирование в базах данных — Bourabai
  10. Use The Index, Luke

Заключение

Индексирование баз данных — фундамент масштабирования: от B-деревьев для диапазонов до bitmap для категорий, оно решает проблему роста данных, делая запросы быстрыми. Главное — баланс: индексируйте по реальным запросам, мониторьте EXPLAIN, избегайте переизбытка. Начните с анализа логов — и ваша БД полетит. В итоге, правильные индексы в БД окупаются сторицей в скорости и оптимизации запросов.

Авторы
Проверено модерацией
Модерация
Как работает индексирование баз данных: принципы