← Назад к вопросам

Почему нельзя везде использовать индексы?

2.0 Middle🔥 111 комментариев
#Базы данных и SQL#Кэширование и производительность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Почему нельзя везде использовать индексы?

Хотя индексы значительно ускоряют чтение данных, их массовое использование приводит к серьёзным проблемам производительности и ресурсоёмкости системы.

Основные причины ограничить количество индексов

1. Замедление операций записи (INSERT, UPDATE, DELETE)

При каждой вставке или обновлении записи база данных должна обновить не только саму таблицу, но и все индексы, которые содержат это значение. Это значительно замедляет операции:

CREATE TABLE users (
  id BIGINT PRIMARY KEY,
  email VARCHAR(255) UNIQUE,
  username VARCHAR(100),
  phone VARCHAR(20),
  created_at TIMESTAMP
);

UPDATE users SET email = 'new@example.com' WHERE id = 1;

На высоконагруженных системах с частыми записями это становится узким местом.

2. Потребление памяти и дискового пространства

Каждый индекс — это отдельная структура данных (B-tree), которая:

  • Занимает память на сервере БД (индексы кешируются в оперативной памяти)
  • Занимает диск (индекс может быть больше самой таблицы)
  • Замедляет backup и репликацию

Таблица users: 100 GB + Индексы: 45 GB = Всего: 145 GB

3. Усложнение плана выполнения запросов

Оптимизатор запросов оценивает множество вариантов выполнения. Много индексов = много вариантов = медленнее принимает решения.

4. Дублирующиеся и пересекающиеся индексы

Часто добавляются индексы, которые дублируют функциональность друг друга:

CREATE INDEX idx_email ON users(email);
CREATE INDEX idx_email_status ON users(email, status);

Индекс на (email, status) можно использовать для поиска по email, но хранится отдельно, потребляя дополнительные ресурсы.

5. Статистика и обслуживание

Индексы требуют регулярной оптимизации (REINDEX, ANALYZE, VACUUM в PostgreSQL). Это добавляет нагрузку на производство и требует планового обслуживания.

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

Добавляй индекс только если:

  • Частые SELECT запросы по этому полю (более 5% всех запросов)
  • В WHERE, JOIN ON или ORDER BY
  • Поле используется в фильтрах и диапазонном поиске

Не добавляй индекс если:

  • Поле редко используется в WHERE (менее 1% запросов)
  • Частые UPDATE/DELETE операции на этой таблице
  • Поле содержит мало уникальных значений (selectivity менее 10%)

Стратегия в Node.js приложении:

const startTime = Date.now();
const users = await db.users.find({ email });
const duration = Date.now() - startTime;

if (duration > 100) {
  console.warn(`Slow query: find by email took ${duration}ms`);
}

Выводы

Индексы — мощный инструмент, но требуют осмысленного применения. Используй 80% времени 20% индексов для частых запросов. Остальные индексы добавляй только по мере необходимости на основе профилирования и анализа медленных запросов (slow query log). Помните о компромиссе: быстрые чтения требуют медленных записей.