Получить доступ

Почему в составном индексе важен порядок колонок?

MiddleИндексы и планы запросовSQLPostgreSQL
Ещё спрашивают так:
  • Что такое правило левого префикса?
  • Как выбрать порядок колонок в составном индексе?
Коротко

Составной индекс (a, b) отсортирован сначала по a, затем по b — как телефонный справочник по фамилии и имени. Поэтому он помогает в поиске по a и по a + b, но не по одному b.

  • Правило левого префикса: используется начало списка колонок
  • Колонки с равенством — первыми, с диапазоном или сортировкой — после
  • Индекс (user_id, created_at) закрывает WHERE user_id = ? ORDER BY created_at DESC LIMIT 20

А ещё Покрывающий индекс (INCLUDE) — запрос обслуживается без чтения таблицы

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Почему порядок важен. B-дерево по (a, b) хранит пары, упорядоченные по a, а при равных a — по b. Найти все строки с a = 5 — один диапазон в индексе. Найти все строки с b = 7 — значения разбросаны по всему индексу, и база выберет полный просмотр (PostgreSQL иногда сканирует весь индекс или использует skip scan в новых версиях, но это дорого).

Как выбирать порядок:

  • колонки, которые сравниваются на равенство, — первыми;
  • затем колонка диапазона (created_at > ...) или сортировки — после диапазонной колонки следующие колонки уже не сужают поиск;
  • смотреть на реальные запросы: один индекс (user_id, status, created_at) может обслужить несколько запросов, начинающихся с user_id;
  • при прочих равных — более селективные колонки раньше.

Покрывающий индекс — включает все колонки, нужные запросу (INCLUDE в PostgreSQL), и запрос выполняется только по индексу (Index Only Scan).

Лишние индексы: индекс (a) не нужен, если есть (a, b) — левый префикс покрывает поиск по a.

Пример

CREATE INDEX ON orders (customer_id, created_at DESC);
SELECT * FROM orders WHERE customer_id = 42 ORDER BY created_at DESC LIMIT 20;  -- индекс целиком
SELECT * FROM orders WHERE created_at > now() - interval '1 day';               -- этот индекс не подходит

Что хотят услышать

  • Как упорядочен составной индекс.
  • Правило левого префикса с примером.
  • Порядок: равенство, затем диапазон и сортировка.
  • Покрывающие индексы и лишние индексы — плюс.

Частые ошибки

  • Ожидать, что индекс (a, b) ускорит поиск только по b.
  • Ставить колонку диапазона перед колонкой равенства.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓B-tree эффективно использует только левый префикс индекса
  • ✗Порядок колонок вообще не влияет на использование индекса
  • ✗Индекс работает только при обратном порядке колонок
  • ✗Порядок колонок определяет уникальность строк

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

  • Что такое covering index?
  • Как EXPLAIN показывает использование индекса?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем