Почему подсказка Mongo заставляет запрос запускаться в 10 раз быстрее?
Если я запустил запрос mongo из оболочки с помощью explain(), получите имя используемого индекса, а затем снова запустил один и тот же запрос, но с подсказкой(), указав тот же самый индекс, который будет использоваться, - поле "millis" из план объяснения значительно снижается
например
нет подсказки:
>>db.event.find({ "type" : "X", "active" : true, "timestamp" : { "$gte" : NumberLong("1317498259000") }, "count" : { "$gte" : 0 } }).limit(3).sort({"timestamp" : -1 }).explain();
{
"cursor" : "BtreeCursor my_super_index",
"nscanned" : 599,
"nscannedObjects" : 587,
"n" : 3,
"millis" : 24,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : true,
"indexOnly" : false,
"indexBounds" : { ... }
}
подсказка:
>>db.event.find({ "type" : "X", "active" : true, "timestamp" : { "$gte" : NumberLong("1317498259000") }, "count" : { "$gte" : 0 } }).limit(3).sort({"timestamp" : -1 }).hint("my_super_index").explain();
{
"cursor" : "BtreeCursor my_super_index",
"nscanned" : 599,
"nscannedObjects" : 587,
"n" : 3,
"millis" : 2,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : true,
"indexOnly" : false,
"indexBounds" : { ... }
}
Единственное различие - поле "миллис"
Кто-нибудь знает, почему это?
UPDATE: "Выбор того, какой индекс использовать" не объясняет, потому что mongo, насколько мне известно, выбирает индекс для каждого прогона X (100?), поэтому он должен быть таким же быстрым, как и с подсказкой next (X -1) выполняется
Ответы
Ответ 1
Mongo использует алгоритм для определения того, какой индекс будет использоваться, когда не будет указана подсказка, а затем кэширует индекс, используемый для аналогичного запроса для следующих 1000 вызовов
Но всякий раз, когда вы объясняете запрос mongo, он всегда запускает алгоритм выбора индекса, поэтому пояснение() с подсказкой всегда будет занимать меньше времени по сравнению с объяснением() без подсказки.
На этот вопрос был дан ответ
Понимание объяснения mongo db
Ответ 2
Mongo выполнил тот же поиск в обоих случаях, сколько вы можете видеть из числа отсканированных объектов. Также вы можете видеть, что используемый индекс был одинаковым (посмотрите на запись "курсор" ), оба использовали уже ваш индекс my_super_index.
"hint" только говорит Mongo использовать тот специфический индекс, который он уже сделал автоматически в первом запросе.
Второй поиск был простым, потому что все данные, вероятно, уже были в кеше.
Ответ 3
Я изо всех сил пытался найти причину для того же самого. Я обнаружил, что когда у нас много индексов, манго действительно занимает больше времени, чем при использовании подсказки. Mongo в основном много времени решает, какой индекс использовать. Подумайте о сценарии, в котором у вас 40 индексов, и вы делаете запрос. Первой задачей, которую должен сделать Mongo, является то, какой индекс лучше всего подходит для конкретного запроса. Это означало бы, что монго нужно сканировать все ключи, а также выполнять некоторые вычисления в каждом сканировании, чтобы найти индекс производительности, если этот ключ используется. подсказка определенно ускорится, так как сканирование индекса ключа будет сохранено.