В типичном сценарии запроса к базе данных Mongodb индекс индекса играет очень важную роль.Если индекса нет, MongoDB необходимо просканировать всю коллекцию, чтобы найти соответствующий документ, что очень дорого.
B-дерево — это специальная структура данных, используемая в индексе Mongodb. С помощью индекса Mongodb может эффективно сопоставлять запрашиваемые данные. Следующий рисунок является примером (с официального сайта):
Индекс оценки может не только эффективно поддерживать запросы диапазона, но также позволяет MongoDB эффективно возвращать отсортированные данные.
Индекс Mongodb очень похож на другие системы баз данных.Индекс Mongodb определяется на уровне коллекции и поддерживает индексирование любого отдельного поля и любого подполя.
дефолт_id
index
MongoDB создает коллекцию на основе_id
Уникальный индекс документа используется как первичный ключ документа, и этот индекс нельзя удалить.
Mongodb поддерживает несколько способов создания индексов, подробнее см. в официальной документации https://docs.mongodb.com/manual/indexes/#create-an-index.
Single field index
Индекс с одним полем — это самый простой тип индекса в MongoDB.В отличие от MySQL, индекс MongoDB является последовательным по возрастанию или по убыванию.
Но для индекса одного поля порядок индекса не имеет значения, поскольку MongoDB поддерживает обход индекса одного поля в любом порядке.
Создайте коллекцию записей здесь:
{
"_id": ObjectId("570c04a4ad233577f97dc459"),
"score": 1034,
"location": { state: "NY", city: "New York" }
}
Затем создайте индекс одного поля:
db.records.createIndex( { score: 1 } )
Приведенный выше оператор создает восходящий индекс в поле оценки коллекции, который поддерживает следующие запросы:
db.records.find( { score: 2 } )
db.records.find( { score: { $gt: 10 } } )
Вы можете использовать объяснение MongoDB для анализа двух вышеуказанных запросов:
db.records.find({score:2}).explain('executionStats')
single index on embedded field
Кроме того, MongoDB также поддерживает создание индекса для встроенных полей:
db.records.createIndex( { "location.state": 1 } )
Встроенный индекс выше поддерживает следующие запросы:
db.records.find( { "location.state": "CA" } )
db.records.find( { "location.city": "Albany", "location.state": "NY" } )
sort on single index
Для одного индекса, поскольку сам индекс MongoDB поддерживает последовательный поиск, для одного индекса
db.records.find().sort( { score: 1 } )
db.records.find().sort( { score: -1 } )
db.records.find({score:{$lte:100}}).sort( { score: -1 } )
Все эти операторы запросов подходят для использования index.
Compound index
MongoDB поддерживает индексирование нескольких полей, которое называется составным индексом. Порядок полей в составном индексе имеет решающее значение для производительности индекса. Например, индекс {userid:1, score:-1} сначала сортируется по идентификатору пользователя, а затем сортируется по количеству баллов в каждом идентификаторе пользователя.
Создать составной индекс
Создайте коллекцию товаров здесь:
{
"_id": ObjectId(...),
"item": "Banana",
"category": ["food", "produce", "grocery"],
"location": "4th Street Store",
"stock": 4,
"type": "cases"
}
Затем создайте составной индекс:
db.products.createIndex( { "item": 1, "stock": 1 } )
Документы, на которые ссылается этот указатель, сначала сортируются по элементам, а затем в каждом элементе сортируются по запасам.Следующие операторы удовлетворяют индексу:
db.products.find( { item: "Banana" } )
db.products.find( { item: "Banana", stock: { $gt: 5 } } )
Условие {item: "Banana"} выполнено, поскольку этот запрос удовлетворяет принципу префикса.
Использование составных индексов должно удовлетворять принципу префикса.
Префикс индекса относится к подмножеству полей индекса с левым префиксом, учитывая следующие индексы:
{ "item": 1, "location": 1, "stock": 1 }
Этот индекс содержит следующие префиксы:
{ item: 1 }
{ item: 1, location: 1 }
Таким образом, пока оператор удовлетворяет принципу префикса индекса, он может поддерживать использование составного индекса:
db.products.find( { item: "Banana" } )
db.products.find( { item: "Banana",location:"4th Street Store"} )
db.products.find( { item: "Banana",location:"4th Street Store",stock:4})
Наоборот, если префикс индекса не удовлетворяет, индекс нельзя использовать, например, следующий запрос поля:
- the location field
- the stock field
- the location and stock fields
Из-за наличия префикса индекса, если коллекция имеет оба{a:1, b:1}индекс, а также{a:1}Индекс, один индекс можно удалить, если нет требований к разреженности или уникальности между ними.
Sort on Compound index
Ранее я говорил, что порядок сортировки одиночного индекса не имеет значения, но составной индекс совершенно другой.
Рассмотрим следующие сценарии:
db.events.find().sort( { username: 1, date: -1 } )
Коллекция событий имеет приведенный выше запрос, сначала результаты сортируются по возрастанию имени пользователя, а затем результаты сортируются по убыванию даты или следующий запрос:
db.events.find().sort( { username: -1, date: 1 } )
Сортировка по убыванию имени пользователя, а затем по возрастанию по дате, индекс:
db.events.createIndex( { "username" : 1, "date" : -1 } )
Поддерживаются оба типа запросов, но не поддерживаются следующие запросы:
db.events.find().sort( { username: 1, date: 1 })
Другими словами, порядок сортировки должен быть таким же, как порядок, в котором был создан индекс. Согласованность означает, что он не обязательно должен быть таким же. Резюме примерно таково.
{ "username" : 1, "date" : -1 } | { "username" : 1, "date" : 1 } | |
---|---|---|
sort( { username: 1, date: -1 } ) | служба поддержки | не поддерживается |
sort( { username: -1, date: 1 } ) | служба поддержки | не поддерживается |
sort( { username: 1, date: 1 } ) | не поддерживается | служба поддержки |
sort( { username: -1, date: -1 } ) | не поддерживается | служба поддержки |
То есть порядок сортировки должен быть таким же, как индекс, и он может быть таким же после обратного порядка., в следующей таблице четко перечислены операторы запроса, которым удовлетворяет составной индекс:
query | index |
---|---|
db.data.find().sort( { a: 1 } ) | { a: 1 } |
db.data.find().sort( { a: -1 } ) | { a: 1 } |
db.data.find().sort( { a: 1, b: 1 } ) | { a: 1, b: 1 } |
db.data.find().sort( { a: -1, b: -1 } ) | { a: 1, b: 1 } |
db.data.find().sort( { a: 1, b: 1, c: 1 } ) | { a: 1, b: 1, c: 1 } |
db.data.find( { a: { $gt: 4 } } ).sort( { a: 1, b: 1 } ) | { a: 1, b: 1 } |
Сортировать по неиндексному префиксу
Рассмотрим индекс { a: 1, b: 1, c: 1, d: 1 }, даже если отсортированное поле не удовлетворяет, префикс индекса в порядке, но предварительное условиеПоле индекса перед полем сортировки должно быть условием равенства,
Example | Index Prefix | |
---|---|---|
r1 | db.data.find( { a: 5 } ).sort( { b: 1, c: 1 } ) | { a: 1 , b: 1, c: 1 } |
r2 | db.data.find( { b: 3, a: 4 } ).sort( { c: 1 } ) | { a: 1, b: 1, c: 1 } |
r3 | db.data.find( { a: 5, b: { $lt: 3} } ).sort( { b: 1 } ) | { a: 1, b: 1 } |
Поля сортировки приведенной выше таблицы r1 — это b и c, a — это поле индекса, и индекс может использоваться перед b и c; при сортировке r3 b — это запрос диапазона, но a перед b также использует эквивалентный условие, то есть до тех пор, пока поле перед полем сортировки может удовлетворять условию равного значения, а другие поля могут иметь любое условие.
Как построить правильный индекс
Предыдущая статья в основном охватывает основные знания об индексах, необходимые для ежедневного использования MongoDB, но как установить правильный индекс?
Используйте объяснение для анализа оператора запроса
По умолчанию MongoDB предоставляет оператор, аналогичный MySQL, объясните, чтобы проанализировать оператор запроса, чтобы помочь нам правильно построить индекс.При построении индекса нам необходимо проанализировать различные условия запроса по сравнению с объяснением.
Понимание влияния порядка полей на индексацию
Реальная функция индекса состоит в том, чтобы помочь нам ограничить диапазон выбора данных. Например, как определить порядок нескольких полей в составном индексе. Мы должны предпочесть поле, которое может минимизировать диапазон поиска данных, так что если первое поле может быстро сузить диапазон поиска данных, тогда в последующих полях совпадающих строк будет гораздо меньше. Рассмотрим утверждение:
{'online_time': {'$lte': present}, 'offline_time': {'$gt': present}, 'online': 1, 'orientation': 'quality', 'id': {'$gt': max_id}}
Рассмотрим следующий индекс
показатель | nscanded | |
---|---|---|
r1 | {start_time:1, end_time: 1, origin: 1, id: 1, orientation: 1} | 12959 |
r2 | {start_time:1, end_time: 1, origin: 1, orientation: 1, id: 1} | 2700 |
из-за поляid
иorientation
Другой порядок данных приведет к огромной разнице в количестве документов, которые необходимо отсканировать, что указывает на то, что два ограничения диапазона данных очень разные, и порядок индекса, который может максимизировать предел диапазона данных отдается приоритет.
Мониторинг медленных запросов
Всегда анализируйте медленные запросы, генерируемые средой генерации в первый раз, находите и решайте проблемы заранее.