Гид по технологиям

Индексы в MongoDB: создание, виды и лучшие практики

5 min read Базы данных Обновлено 21 Dec 2025
Индексы в MongoDB — создание и лучшие практики
Индексы в MongoDB — создание и лучшие практики

Взаимосвязанные жёсткие диски серверов

TL;DR

Индексы в MongoDB ускоряют чтение и селекцию данных, но увеличивают стоимость записи и хранения. Научитесь создавать одиночные, multikey и составные индексы, проверять их эффект и выбирать стратегию по нагрузке приложения.

Важно: MongoDB по умолчанию создаёт индекс по полю _id — это обеспечивает быстрый поиск по идентификатору документа.

Что такое индекс в MongoDB

Индекс — это вспомогательная структура данных, которая упорядочивает значения полей коллекции для быстрой выборки. Она позволяет БД выполнять поиск и сортировку без полного сканирования коллекции.

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

Ключевые эффекты индексирования:

  • Быстрые операции чтения по индексируемым полям.
  • Сортировка без дополнительной операции sort, если индекс уже содержит порядок.
  • Возможность задать уникальность для предотвращения дубликатов.

Когда индексы помогают и когда нет

  • Полезно: частые фильтры по конкретным полям, сортировка по дате, поиск по уникальным ключам (например, email, username).
  • Неэффективно: малое количество уникальных значений (low cardinality), частые массовые вставки без пакетирования, запросы, которые возвращают почти всю коллекцию.

Пример неэффективности: индекс по полю boolean часто бессмыслен — селект указывает на ~50% документов и индекс не экономит чтение.

Как создать индекс в MongoDB

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

Примеры в mongo shell.

Создать одиночный индекс по полю age, сортировка по убыванию:

db.userCollection.createIndex({age: -1})

Пояснение: значение -1 означает сортировку по убыванию; 1 означает по возрастанию.

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

Выбор базы данных

use MUO

Создание одиночного индекса

Одиночный индекс по имени пользователя, сортировка по убыванию:

db.collectionName.createIndex({username: -1})

Multikey индекс

Multikey индекс нужен, если поле — массив или вложенный объект и вы хотите индексировать элементы массива.

Пример: индекс по росту пользователей внутри массива user:

db.customers.createIndex({"user.height": 1})

MongoDB создаст отдельный индексный ключ для каждого элемента массива.

Составной индекс

Если запрос сочетает фильтры по нескольким полям, часто полезен составной (compound) индекс.

Пример простого составного индекса по адресу и типу продукта:

db.customer.createIndex({address: 1, products: 1})

По умолчанию MongoDB сформирует имя индекса из полей, разделённых подчёркиванием. Чтобы задать читаемое имя:

db.customers.createIndex({location: 1, products: 1, weight: -1}, {name: "myCompoundIndex"})

Просмотр всех индексов коллекции

db.collectionName.getIndexes()

Команда вернёт массив объектов с описанием каждого индекса, включая имя, ключи и опции.

Практическая методология выбора индекса (мини‑метод)

  1. Соберите метрики запросов: какие поля используются в фильтрах и сортировках.
  2. Отсортируйте поля по частоте использования и селективности (сколько уникальных значений).
  3. Для частых точечных запросов создайте одиночные индексы по этим полям.
  4. Для запросов с несколькими полями создайте составной индекс в порядке, соответствующем использованию в фильтре и сортировке.
  5. Тестируйте план выполнения (explain) и измеряйте latency и I/O.
  6. Ревью: удаляйте неиспользуемые индексы, чтобы снизить накладные расходы на записи.

Проверка эффективности: explain и профилирование

Всегда проверяйте, как запрос использует индекс:

db.collectionName.find({age: {$gt: 50}}).sort({date: -1}).explain("executionStats")

explain возвращает план выполнения и показывает, использовал ли MongoDB индекс или сделал COLLSCAN. По executionStats можно увидеть количество прочитанных документов и операций.

Типичные ошибки и когда индексы «не работают» (контрпримеры)

  • Индекс по полю с малой кардинальностью (например, boolean) почти не ускорит запрос.
  • Неправильный порядок полей в составном индексе — запрос может не использовать индексовую префиксную часть.
  • Создание слишком большого числа индексов удорожает вставки и обновления.
  • Запросы с функциями над полем (например, вычисления в фильтре) не используют индекс.

Альтернативные подходы и когда их применять

  • Кэширование в памяти (Redis) для быстрого доступа к результатам частых запросов.
  • Денормализация: хранить предвычисленные поля или агрегаты рядом с документом.
  • Aggregation pipeline с материализованными результатами для сложных аналитических задач.
  • TTL‑индексы для автоматического удаления устаревших данных.

Ментальные модели и эвристики

  • Heuristic 1: при частоте запросов > 1/sec по полю — подумайте про индекс.
  • Heuristic 2: высокая селективность -> индекс полезен; низкая селективность -> бесполезен.
  • Heuristic 3: если индекс улучшает латентность чтения, но ухудшает важную подачу записей — оцените компромисс.

Ролевые чеклисты

Разработчик:

  • Определить поля для фильтрации и сортировки.
  • Написать тестовые запросы и выполнить explain.
  • Предложить индексы и проверить влияние на вставки.

DBA / Администратор БД:

  • Проверить суммарный объём индексов и влияние на IOPS.
  • Настроить расписание создания/удаления индексов в maintenance window.
  • Мониторить пропускную способность и latencies операции записи.

Менеджер продукта:

  • Оценить требования к SLA для latency чтения и записи.
  • Утвердить компромиссы между скоростью чтения и стоимостью хранения.

Сниппет / шпаргалка по командам

use MUO
// Создать одиночный индекс
db.users.createIndex({age: -1})
// Multikey индекс
db.collection.createIndex({"tags": 1})
// Составной индекс с именем
db.orders.createIndex({userId: 1, createdAt: -1}, {name: "user_createdAt_idx"})
// Список индексов
db.orders.getIndexes()
// Удалить индекс по имени
db.orders.dropIndex("user_createdAt_idx")
// Проверить план выполнения
db.orders.find({userId: 123}).explain("executionStats")

Критерии приёмки (что проверить после создания индекса)

  • Запросы, для которых создавался индекс, используют этот индекс (explain показывает IDXSCAN).
  • Latency запросов снизился до ожидаемого уровня.
  • Нагрузка на запись не выросла сверх допустимой.
  • Потребление дискового пространства индексами соответствует ожиданиям.

Пример использования: сортировка по дате без sort

Если требуется часто получать записи по убыванию даты, создайте индекс с порядком сортировки:

db.events.createIndex({date: -1})

После этого запрос

db.events.find({type: "login"})

может возвращать документы уже в нужном порядке без операции sort.

Decision flowchart для выбора типа индекса

flowchart TD
  A[Какие поля в запросах?] --> B{Поле одно или массив?}
  B -->|Одиночное поле| C[Одиночный индекс]
  B -->|Массив или вложенное| D[Multikey индекс]
  A --> E{Несколько полей}
  E -->|Частые фильтры и сортировка| F[Составной индекс]
  E -->|Редко комбинируются| G[Несколько одиночных индексов]
  C --> H[Проверить explain и метрики]
  D --> H
  F --> H
  G --> H

Факто-бокс

  • MongoDB создаёт индекс по полю _id по умолчанию.
  • Индексы улучшают чтение, но увеличивают затрату на вставки и обновления.
  • Multikey‑индекс пригоден для массивов и создаёт ключи для каждого элемента.

Риски и смягчения

  • Риск: слишком много индексов замедляет запись. Смягчение: мониторить write latency и удалять редко используемые индексы.
  • Риск: неправильный порядок полей в составном индексе. Смягчение: тестировать explain и проверять использование префикса.

Глоссарий (1 строка)

  • Индекс: структура для быстрого доступа к документам по значению поля.
  • Multikey: индекс для полей, содержащих массивы или вложенные документы.
  • Составной индекс: индекс по нескольким полям, учитывающий порядок полей.

Заключение

Индексы — ключевой инструмент оптимизации запросов в MongoDB. Они позволяют значительно сократить время чтения и упростить сортировки, но требуют компромисса с затратами на запись и дисковое пространство. Применяйте методологию: анализируйте частоту и селективность запросов, создавайте индексы по приоритету и обязательно проверяйте план выполнения с помощью explain.

Краткий план действий:

  1. Собрать профили запросов.
  2. Выбрать кандидатов на индексацию.
  3. Создать индекс в тестовой среде.
  4. Измерить влияние и утвердить изменение в продакшене.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Отключить рекламу в Windows 11
Советы

Отключить рекламу в Windows 11

Как собрать кастомный Mac на сайте Apple
Mac

Как собрать кастомный Mac на сайте Apple

Как использовать профили в Firefox
Браузеры

Как использовать профили в Firefox

Стриминг Xbox на Android через Remote Play
Гайды

Стриминг Xbox на Android через Remote Play

Личный бренд в интернете: шаг за шагом
Карьера

Личный бренд в интернете: шаг за шагом

Как Adobe использует файлы для обучения ИИ — как отключить
Конфиденциальность

Как Adobe использует файлы для обучения ИИ — как отключить