Можно ли создать составной индекс на несколько колонок?
Что проверяют
Знаете ли вы правило левого префикса и понимаете ли, что в составном индексе порядок колонок важнее их набора. Вопрос на умение читать план запроса, а не на синтаксис.
Как отвечать
Да, составной индекс есть во всех реляционных базах:
create index orders_user_created_idx on orders (user_id, created_at);Такой индекс работает для условий по первой колонке и по паре колонок, но для запроса только по дате он бесполезен: используется левый префикс индекса. Порядок колонок в самом where при этом неважен, планировщик их переставит сам.
Как выбирать порядок:
- сначала колонки, по которым всегда идёт равенство, затем диапазон и сортировка;
- после колонки с диапазоном следующие колонки поиск уже не сужают, а только фильтруют найденное;
- индекс может закрыть и
order by, если направления сортировки совпадают с объявленными; - если в индекс входят все колонки запроса, чтение идёт по индексу без похода в таблицу.
Цена тоже должна прозвучать: каждый индекс замедляет запись и занимает место, поэтому набор индексов подбирают под реальные запросы, а не «на всякий случай».
Где спотыкаются
Создают по отдельному индексу на каждую колонку и ждут, что база их соединит. Соединение индексов существует, но обходится дороже одного правильно составленного.
Ставят первой колонку с двумя значениями вроде флага или статуса. Первой должна идти та, по которой в запросах всегда есть равенство, а редкий флаг чаще уместнее в условии частичного индекса.
Полагаются на Hibernate. Аннотация @Index внутри @Table попадает только в схему, которую генерирует сам Hibernate, а на бою схему катает миграция, и автогенерация там отключена. Индекс надо писать в миграции руками.