为什么Mongo提示使查询运行速度提高了10倍?

时间:2011-10-11 18:20:12

标签: mongodb indexing hint

如果我使用explain()从shell运行mongo查询,获取所用索引的名称,然后再次运行相同的查询,但使用hint()指定要使用的相同索引 - 来自“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" : { ... }
} 

唯一的区别是“millis”字段

有谁知道为什么会这样?

更新:“选择使用哪个索引”并没有解释它,因为据我所知,mongo为每个X(100?)运行选择索引,因此它应该与下一个提示一样快(X -1)运行

4 个答案:

答案 0 :(得分:20)

Mongo使用算法来确定在没有提供提示时使用哪个索引,然后缓存用于下次1000次调用的类似查询的索引

但是每当你解释一个mongo查询时,它总会运行索引选择算法,因此与没有提示的explain()相比,带提示的explain()总是花费更少的时间。

这里回答了类似的问题 Understanding mongo db explain

答案 1 :(得分:6)

从扫描对象的数量可以看出,Mongo两次都进行了相同的搜索。您还可以看到使用的索引是相同的(看看“cursor”条目),两者都已经使用了my_super_index索引。

“提示”只告诉Mongo使用它在第一个查询中已自动执行的特定索引。

第二次搜索更简单,因为所有数据可能已经在缓存中了。

答案 2 :(得分:2)

我努力找到同样的理由。我发现当我们有很多索引时,mongo确实比使用提示花费更多时间。 Mongo基本上花了很多时间来决定使用哪个索引。想想你有40个索引并进行查询的场景。 Mongo需要做的第一个任务是哪个索引最适合用于特定查询。这意味着mongo需要扫描所有键,并在每次扫描中进行一些计算,以便在使用此键时找到一些性能指标。由于索引键扫描将被保存,提示肯定会加快。

答案 3 :(得分:0)

我会告诉你如何找出更快的速度 1)没有索引    它将所有文档拉入内存以获取结果 2)带索引    如果该集合有很多索引,它将从缓存中获取索引 3)与.hint(_index)    将使用您提到的特定索引

有hint()而没有hint() 两次都 .explain(“ executionStats”) 使用hint(),则可以检查 totalKeysExamined 值,该值将与 totalDocsExamined 相匹配 没有hint()的情况下,您会看到 totalKeysExamined 的值更高,然后 totalDocsExamined

totalDocsExamined ,此结果在大多数情况下将与结果计数完全匹配。