Индексы и производительность
Индекс — это структура данных, которая ускоряет поиск. Без индекса СУБД читает всю таблицу. С индексом — сразу находит нужные строки.
Когда нужен индекс
- Колонка часто используется в
WHERE - Колонка участвует в
JOIN - Колонка используется для сортировки
ORDER BY - Колонка часто проверяется на уникальность
Когда индекс вреден
- Таблица маленькая
- Колонка редко используется в запросах
- Много операций вставки (индекс замедляет INSERT)
Обычный индекс
$table->string('status')->index();
$table->index('created_at');
Составной индекс:
$table->index(['status', 'created_at']);
Порядок колонок важен: индекс (status, created_at) ускоряет запросы по status, но не по одному created_at.
Уникальный индекс
$table->string('email')->unique();
$table->unique(['user_id', 'slug']);
Первичный ключ
$table->primary('id');
$table->primary(['user_id', 'role_id']);
Полнотекстовый индекс
Для поиска по тексту (MySQL, PostgreSQL):
$table->fullText('body');
Использование:
Post::whereFullText('body', 'laravel')->get();
Spatial
Для геоданных:
$table->geometry('location')->spatialIndex();
Имя индекса
По умолчанию Laravel генерирует имя из таблицы и колонок. Можно задать вручную:
$table->index('status', 'posts_status_idx');
Удаление индекса
$table->dropIndex(['status']);
$table->dropUnique(['email']);
$table->dropPrimary('id');
Проверка индексов
В PostgreSQL:
\d posts
В MySQL:
SHOW INDEX FROM posts;
Антипаттерны
- Индекс на каждую колонку — замедляет запись
- Составной индекс с неправильным порядком колонок
- Индекс на колонку с малым числом уникальных значений (например,
boolean) - Дублирующиеся индексы