Почему подсказка Mongo заставляет запрос работать в 10 раз быстрее?

Если я запускаю запрос mongo из оболочки с помощью explain (), получите имя используемого индекса, а затем снова запустите тот же запрос, но с подсказкой (), указывающей тот же индекс, который будет использоваться - поле "millis" из плана explain значительно уменьшается

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

>>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" : { ... }
} 

единственная разница-поле "Миллис"

кто-нибудь знает почему?

обновление: "Выбор индекса для использования" не объясняет этого, потому что монго, насколько я знаю, выбирает индекс для каждого X (100?) работает, поэтому он должен быть так же быстро, как с подсказкой next (X-1) runs

3 ответов


Mongo использует алгоритм, чтобы определить, какой индекс будет использоваться, когда нет подсказки, а затем кэширует индекс, используемый для аналогичного запроса для следующих 1000 вызовов

но всякий раз, когда вы объясняете запрос mongo, он всегда будет запускать алгоритм выбора индекса, поэтому explain() с подсказкой всегда будет занимать меньше времени по сравнению с explain() без подсказки.

аналогичный вопрос был дан ответ здесь понимание mongo db объяснить


Монго сделал тот же поиск оба раза, как вы можете видеть из числа отсканированных объектов. Также вы можете видеть, что используемый индекс был одинаковым (взгляните на запись "курсор"), оба использовали уже ваш индекс my_super_index.

"подсказка" только говорит Монго использовать тот конкретный индекс, который он уже автоматически сделал в первом запросе.

второй поиск был просто быстрее, потому что все данные уже в кэше.


Я изо всех сил пытался найти причину для того же самого. Я обнаружил, что когда у нас много индексов, mongo действительно занимает больше времени, чем использование подсказки. Монго в основном занимает много времени, решая, какой индекс использовать. Подумайте о сценарии, в котором у вас есть 40 индексов, и вы делаете запрос. Первая задача, которую должен выполнить Монго, - это какой индекс лучше всего подходит для конкретного запроса. Это означало бы, что mongo должен сканировать все ключи, а также выполнять некоторые вычисления в каждом сканировании, чтобы найти некоторые performancce индексировать, если используется этот ключ. подсказка определенно ускорится, так как сканирование ключа индекса будет сохранено.