Мастерство составных индексов в MongoDB
Это руководство углубляется в тонкости составных индексов в MongoDB — критически важной техники для оптимизации производительности базы данных. Мы рассмотрим все, от понимания их фундаментальной работы до анализа их эффективности и устранения распространенных проблем.
- Понимание составных индексов
- Создание составных индексов
- Запросы с составными индексами
- Анализ использования индексов
- Рекомендации и оптимизация
- Часто задаваемые вопросы
1. Понимание составных индексов
В MongoDB составной индекс — это индекс, охватывающий несколько полей в одном документе. В отличие от индексов по одному полю, которые ускоряют только запросы по одному полю, составные индексы резко повышают скорость запросов, включающих несколько полей, значительно влияя на производительность приложения. Порядок полей в индексе имеет решающее значение; MongoDB использует этот порядок для эффективного поиска документов.
Запросы, соответствующие ведущим полям индекса, получают наибольшую выгоду. Если запрос использует только ведущие поля, индекс полностью используется как для фильтрации, так и для сортировки. Однако, если запрос использует поля за пределами индекса, MongoDB может частично использовать индекс, потенциально возвращаясь к полному сканированию коллекции для оставшихся критериев, сводя на нет прирост производительности.
Например, рассмотрим коллекцию products
с полями category
, price
и name
. Составной индекс по { "category": 1, "price": -1 }
оптимизирует запросы, фильтрующие по category
и затем сортирующие по price
в убывающем порядке.
2. Создание составных индексов
Создание составных индексов осуществляется с помощью метода db.collection.createIndex()
. Аргументом является документ, где ключи представляют имена полей, а значения — порядок сортировки (1 для возрастающего, -1 для убывающего).
// Создание составного индекса по category (возрастающий) и price (убывающий)
db.products.createIndex( { category: 1, price: -1 } );
// Создание составного индекса по нескольким полям с различным порядком сортировки
db.users.createIndex( { firstName: 1, lastName: -1, age: 1 } );
// Добавление параметров unique и sparse
db.products.createIndex( { category: 1, price: -1 }, { unique: true, sparse: true } );
unique: true
обеспечивает уникальность по индексируемым полям, а sparse: true
индексирует только документы, где индексируемые поля не равны null.
3. Запросы с составными индексами
Оптимизатор запросов MongoDB автоматически использует составной индекс, если запрос соответствует ведущим полям, и порядок сортировки совпадает. Например, следующий запрос выигрывает от индекса { "category": 1, "price": -1 }
:
db.products.find( { category: "Electronics" } ).sort( { price: -1 } );
Этот запрос фильтрует по category
(ведущее поле индекса) и сортирует по price
(соответствует порядку сортировки индекса). Однако этот запрос не получит такой же выгоды:
db.products.find( { price: { $lt: 100 } } ).sort( { category: 1 } );
price
не является ведущим полем, и порядок сортировки не соответствует индексу.
4. Анализ использования индексов
Используйте db.collection.find().explain()
для анализа использования индексов. Это предоставляет подробную информацию о плане выполнения запроса, включая то, какие индексы использовались (или нет) и время выполнения.
db.products.find( { category: "Electronics" } ).sort( { price: -1 } ).explain();
Изучите раздел «executionStats». Если индекс используется, вы увидите использование индексных ключей и количество проверенных документов. «COLLSCAN» указывает на полное сканирование коллекции, менее эффективное, чем использование индекса.
5. Рекомендации и оптимизация
Тщательный выбор индексов имеет решающее значение. Чрезмерное индексирование замедляет операции записи, а недостаточное индексирование приводит к неэффективным запросам. Приоритезируйте часто используемые шаблоны запросов, добавляя индексы по мере необходимости. Регулярно отслеживайте использование индексов и корректируйте их в соответствии с потребностями приложения. Рассмотрите возможность использования графического интерфейса MongoDB Compass для упрощенного управления индексами.
6. Часто задаваемые вопросы
- Сколько составных индексов следует создавать? Оптимальное количество зависит от шаблонов запросов вашего приложения. Необходимо найти баланс, чтобы избежать чрезмерного индексирования.
- Что делать, если мой запрос не идеально соответствует индексу? MongoDB может использовать части индекса, но все же может прибегнуть к сканированию всей коллекции для несоответствующих частей.
- Можно ли создавать составные индексы со смешанными возрастающими/убывающими полями? Да, порядок имеет решающее значение для оптимальной производительности.
- Как удалить составной индекс? Используйте
db.collection.dropIndex()
, указав имя индекса или спецификацию:
// Удаление по имени
db.products.dropIndex("category_1_price_-1");
// Удаление по спецификации
db.products.dropIndex( { category: 1, price: -1 } );