Ответ
Составной (или композитный) индекс — это индекс в базе данных, который строится сразу по нескольким колонкам одной таблицы. Он используется для ускорения запросов, которые фильтруют, сортируют или группируют данные по этим колонкам одновременно.
Зачем они нужны?
Представьте запрос:
SELECT * FROM users WHERE company_id = 123 AND status = 'active';
Если у вас есть два отдельных индекса (один по company_id
, другой по status
), СУБД сможет эффективно использовать только один из них. С составным индексом по (company_id, status)
база данных сможет мгновенно найти все нужные строки.
Ключевые правила и принципы
Порядок колонок критически важен. Индекс по
(col1, col2)
будет эффективно использоваться для запросов с условиями:WHERE col1 = ?
WHERE col1 = ? AND col2 = ?
Но он будет малоэффективен или бесполезен для запросаWHERE col2 = ?
.
Селективность. Ставьте колонки с наибольшим количеством уникальных значений (наиболее селективные) в начало индекса. Например, в индексе
(status, user_id)
лучше поменять порядок на(user_id, status)
, так какuser_id
гораздо уникальнее, чемstatus
.Избегайте избыточности. Если у вас есть составной индекс по
(col1, col2)
, то отдельный индекс поcol1
в большинстве случаев не нужен, так как он уже покрывается составным.
Применение в Go
При работе с базами данных из Go, например, через ORM GORM, составные индексы можно объявлять прямо в моделях с помощью тегов.
import "gorm.io/gorm"
type User struct {
gorm.Model
FirstName string `gorm:"index:idx_name"` // Обычный индекс
LastName string `gorm:"index:idx_name"` // Такое же имя создает составной индекс
// Другой способ, более явный
Country string `gorm:"index:idx_country_city"`
City string `gorm:"index:idx_country_city"`
}
// При автомиграции GORM создаст SQL-код, аналогичный этому:
// CREATE INDEX idx_name ON users (first_name, last_name);
// CREATE INDEX idx_country_city ON users (country, city);
Правильное использование составных индексов — ключевой навык для оптимизации производительности бэкенд-приложений, работающих с большими объемами данных.