Будет ли эффективно использоваться составной индекс по полям A и B, если запрос использует только поле A
Что проверяют
Понимаете ли вы правило левого префикса. Это ежедневное знание при проектировании индексов, и ошибка здесь стоит медленных запросов на проде.
Как отвечать
Да, индекс по (A, B) работает для запроса только по A. Составной индекс хранит записи отсортированными сначала по первому полю, затем по второму, поэтому все строки с нужным значением A лежат подряд, и база находит их за то же число шагов, что и по одиночному индексу по A. Отдельный индекс только по A при наличии (A, B) обычно избыточен.
Обратное неверно: запрос только по B этот индекс использовать нормально не может, потому что значения B разбросаны по всему дереву. В таком случае нужен свой индекс по B или порядок полей (B, A).
Отсюда правила выбора порядка колонок:
- первым ставят поле, по которому чаще идёт равенство;
- поле с диапазоном (
>,BETWEEN,LIKE 'x%') ставят последним: после него остальные колонки индекса для отбора уже не работают, только для сортировки; - полезен индекс и для
ORDER BY, если порядок сортировки совпадает с порядком колонок в индексе; - если в индекс входят все колонки запроса, база может ответить, вообще не заглядывая в таблицу.
Проверяется всё это одним способом: посмотреть фактический план через EXPLAIN (ANALYZE, BUFFERS) и убедиться, что индекс действительно выбран.
Где спотыкаются
Создают отдельный индекс по каждой колонке вместо одного составного и удивляются, что запись просела.
Ставят диапазонное поле первым, после чего вторая колонка перестаёт помогать отбору.
Забывают, что функция или приведение типа над колонкой отключает индекс: where date(created_at) = ... требует индекса по выражению.