Какой индекс предложить для запроса с условиями по курсу студента и полу и почему
Что проверяют
Умеете ли вы думать об индексе через селективность и порядок колонок, а не отвечать «индекс на оба поля» по привычке. Следом обычно спрашивают, как проверить, что база этот индекс реально берёт, и что изменится, если в запросе появится сортировка или условие только по курсу.
Как отвечать
Начните с данных. Курсов обычно от четырёх до шести, у пола два значения, то есть сочетаний около десятка. Если запрос возвращает заметную долю таблицы, планировщик честно выберет последовательное чтение, и никакой индекс не поможет. Индекс окупается, когда таблица большая, а результат узкий, или когда к условиям добавляются более избирательные поля.
Каркас ответа:
- составной B-tree
(course, gender): закрывает оба равенства. Для чистого равенства порядок колонок на скорость почти не влияет, ноcourseставят первым: по курсу фильтруют и отдельно, а индекс работает слева направо; - отдельный индекс по
gender: почти бесполезен, у двух значений нет селективности; - покрывающий индекс:
CREATE INDEX ... ON students (course, gender) INCLUDE (name)в PostgreSQL даёт Index Only Scan, если запрос читает только эти поля; - частичный индекс: если всегда ищут, например, только активных студентов, условие
WHERE is_activeделает индекс меньше; - сортировка: при
ORDER BY last_nameимеет смысл(course, gender, last_name), тогда база отдаст строки уже упорядоченными.
Проверку покажите через EXPLAIN (ANALYZE, BUFFERS) на реальном объёме. Со стороны Go добавьте, что значения передаются плейсхолдерами ($1, $2 в pgx или database/sql), а не склеиваются через fmt.Sprintf: это заодно защита от инъекций.
Где спотыкаются
Предлагают два отдельных индекса по курсу и полу. PostgreSQL умеет склеить их через Bitmap AND, но это дороже одного составного, а индекс по полу сам по себе не нужен.
Не упоминают селективность. Если студентов 2000, а под условие попадает каждый десятый, полный проход по таблице дешевле, и интервьюер ждёт, что вы скажете это сами.
Обещают, что индекс «ускорит в разы», не заглянув в план. Без EXPLAIN ANALYZE на объёме, близком к боевому, такие обещания ничего не стоят.