Можно ли создать индекс на часть таблицы, например на диапазон значений
Что проверяют
Знаете ли вы про частичные индексы и понимаете ли, что это возможность конкретной СУБД, а не стандарта SQL. Java-кандидату заодно проверяют, где такой индекс должен объявляться в проекте.
Как отвечать
Да, если база это умеет. В PostgreSQL индекс с условием создаётся так:
create index orders_new_created_idx on orders (created_at)
where status = 'new';Расклад по базам: в PostgreSQL это частичный индекс, в SQL Server то же самое называется отфильтрованным. В MySQL условия у индекса нет вовсе, там есть префиксные индексы по длине строки, а это совсем про другое. В Oracle предиката тоже нет, вместо него применяют функциональный индекс, пользуясь тем, что полностью пустые ключи в B-дерево не попадают.
Зачем это нужно: индекс меньше, дешевле обновляется и лучше держится в кэше. Классический случай, когда горячая часть таблицы это малая доля строк: активные записи, необработанная очередь, неудалённые сущности. Отдельная польза у уникального частичного индекса: он даёт уникальность не по всей таблице, а только среди строк, подходящих под условие, например среди неудалённых.
Где спотыкаются
Отвечают «да, во всех современных СУБД». MySQL в этом списке лишний, и уточняющий вопрос про него задают сразу же.
Думают, что такой индекс задаётся аннотацией. У @Index в JPA условия нет, Hibernate его не сгенерирует: частичный индекс это DDL, и место ему в миграции Flyway или Liquibase.
Создают индекс и удивляются, что план его не берёт. Планировщик обязан доказать, что условие запроса влечёт условие индекса, а Hibernate подставляет значение параметром, и на параметре доказательство не строится. Нужна константа в самом запросе либо индекс по более широкому условию.