Индексы: зачем и когда
индекс ускоряет поиск строк по столбцу, избавляя БД от сканирования всей таблицы.
Почему это важно: Отсутствие индексов — одна из самых частых причин медленных API. Добавление одного индекса может ускорить запрос с минут до миллисекунд.
Главная идея
Индекс — это дополнительная структура данных (обычно B-дерево), которая хранит отсортированные значения столбца с указателями на строки таблицы.
Как это выглядит на практике
- Запрос WHERE email = 'user@example.com' без индекса сканирует всю таблицу (seq scan).
- CREATE INDEX idx_users_email ON users(email) создаёт индекс.
- Теперь БД находит строку через B-дерево за O(log n) вместо O(n).
- EXPLAIN ANALYZE показывает Index Scan вместо Seq Scan.
Что происходит под капотом
- B-tree индекс — стандарт для большинства запросов; поддерживает =, <, >, BETWEEN, ORDER BY.
- Hash-индекс — только для точного совпадения (=); быстрее B-tree для этого случая.
- GIN/GiST индексы — для полнотекстового поиска и JSON-полей (PostgreSQL).
- Каждый индекс занимает место на диске и замедляет INSERT/UPDATE/DELETE, потому что индекс нужно обновлять.
Типичные ошибки и заблуждения
- Ошибка: индексы нужно добавить на все столбцы. Лишние индексы замедляют запись и занимают место.
- Ошибка: индекс всегда ускорит запрос. Для небольших таблиц seq scan может быть быстрее.
- Ошибка: индекс работает с LIKE '%pattern'. Начальный wildcard не позволяет использовать индекс.
- Ошибка: индексы не нужны для foreign key. Foreign key без индекса замедляет каскадные операции и JOIN.
Ключевые выводы
- Индекс ускоряет чтение за счёт дополнительного места и замедления записи.
- Добавляйте индексы на столбцы в WHERE, JOIN ON и ORDER BY.
- EXPLAIN ANALYZE — инструмент проверки использования индексов.
- Foreign key всегда должен быть проиндексирован.
Термины урока
Связь с работой backend-разработчика
Добавляйте индексы на основании реальных медленных запросов (EXPLAIN, slow query log), а не заранее. Преждевременная индексация — расточительство ресурсов.
Мини-разбор реальной ситуации
Запрос users WHERE email = ? работает 3 секунды на таблице из 2 миллионов строк. EXPLAIN показывает Seq Scan. CREATE INDEX CONCURRENTLY idx_users_email ON users(email) — индекс создаётся без блокировки таблицы. Запрос начинает работать за 1 мс.
Что запомнить
- Индексируйте столбцы в WHERE, JOIN и ORDER BY по мере необходимости.
- Каждый индекс замедляет запись — не создавайте их без причины.
- EXPLAIN ANALYZE — ваш главный инструмент оптимизации запросов.
Итог
Индексы — главный рычаг оптимизации SQL-запросов. Правильно выбранный индекс превращает секунды в миллисекунды.