Ответ
Порядок полей в составном индексе критически важен для производительности запросов и определяется в первую очередь структурой ваших WHERE
и ORDER BY
выражений, а не только селективностью (кардинальностью) данных.
Основное правило: Поля в индексе должны идти в том же порядке, в котором они используются в WHERE
.
Представьте индекс как отсортированную телефонную книгу. Индекс по (фамилия, имя)
позволяет быстро найти:
- Всех с фамилией
Иванов
. - Конкретного
Иванова Ивана
.
Но он бесполезен для быстрого поиска всех людей с именем Иван
без указания фамилии.
Рекомендации по порядку полей:
- Равенство (
=
,IN
): Сначала идут поля, которые фильтруются по точному значению. - Диапазон (
>
,<
,BETWEEN
): Затем поля, используемые в диапазонах. В одном индексе эффективно может использоваться только одно поле с диапазоном. - Сортировка (
ORDER BY
): В конце — поля для сортировки, если направление сортировки в запросе и в индексе совпадает.
Пример:
Для запроса SELECT * FROM users WHERE country = 'RU' AND city = 'Moscow' ORDER BY registration_date;
идеальным будет индекс:
-- Сначала поля для точного поиска, затем для сортировки
CREATE INDEX idx_users_country_city_reg_date ON users(country, city, registration_date);
Такой индекс будет малоэффективен или не будет использоваться для запросов, где фильтрация идет только по city
или registration_date
.
В Go при использовании ORM (например, GORM) это выглядит так:
db.Model(&User{}).AddIndex("idx_users_country_city_reg_date", "country", "city", "registration_date")