Урок 06

Индексы и производительность

Индекс — это структура данных, которая ускоряет поиск. Без индекса СУБД читает всю таблицу. С индексом — сразу находит нужные строки.

Когда нужен индекс

  • Колонка часто используется в 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)
  • Дублирующиеся индексы