22

如果我使用 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" : { ... }
} 

唯一的区别是“毫”字段

有谁知道这是为什么?

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

4

4 回答 4

27

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

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

在这里回答了类似的问题 理解 mongo db explain

于 2013-02-21T11:22:22.740 回答
6

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

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

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

于 2012-03-27T19:28:31.210 回答
2

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

于 2012-08-21T08:19:32.417 回答
0

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

使用hint() 没有hint() 两次使用hint() 进行.explain("executionStats" ) 然后您可以检查totalKeysExamined值,该值将与没有hint() 的totalDocsExamined匹配, 您可以看到totalKeysExamined值大于totalDocsExamined

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

于 2019-04-22T14:07:30.417 回答