51. Подобрать индекс для медленного запроса
Условие задачи:
В приложении медленно выполняется запрос:
SELECT id, name
FROM users
WHERE name = 'Artem'
AND create_date = '2024-10-28'
AND status = 'ACTIVE';
Необходимо определить, какой индекс стоит добавить для ускорения этого запроса.
Спойлеры к решению
Подсказки
💡 Для такого запроса обычно подходит составной индекс по колонкам из
WHERE.💡 Все три условия используют сравнение по равенству, поэтому для данного конкретного запроса порядок этих колонок в индексе обычно не является критичным.
💡 Порядок становится важнее, если этот же индекс должен использоваться и другими запросами только по части колонок.
💡 После создания индекса проверь план выполнения через
EXPLAIN ANALYZE.Решение
Для данного запроса можно создать составной индекс:
CREATE INDEX idx_users_name_create_date_status
ON users (name, create_date, status);
Он соответствует условиям фильтрации:
WHERE name = 'Artem'
AND create_date = '2024-10-28'
AND status = 'ACTIVE'
и позволяет СУБД искать подходящие строки по индексу вместо полного просмотра таблицы, если использование индекса действительно выгодно для имеющихся данных.
Поскольку во всех трёх условиях используется =, для именно этого запроса варианты:
(name, create_date, status)
и, например:
(create_date, status, name)
могут одинаково эффективно ограничивать выборку по всем трём колонкам.
Выбирать порядок только по правилу «самая селективная колонка всегда первая» не обязательно. Порядок особенно важен, если индекс должен поддерживать также запросы по его левому префиксу. Например, индекс:
CREATE INDEX idx_users_name_create_date_status
ON users (name, create_date, status);
может быть полезен и для запросов только по name или по name вместе с create_date.
После создания индекса следует проверить реальный план:
EXPLAIN ANALYZE
SELECT id, name
FROM users
WHERE name = 'Artem'
AND create_date = '2024-10-28'
AND status = 'ACTIVE';
При этом наличие Seq Scan само по себе не означает проблему: если таблица небольшая или условию соответствует значительная часть строк, полный просмотр таблицы может оказаться дешевле использования индекса.