如果我使用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)运行
答案 0 :(得分:20)
Mongo使用算法来确定在没有提供提示时使用哪个索引,然后缓存用于下次1000次调用的类似查询的索引
但是每当你解释一个mongo查询时,它总会运行索引选择算法,因此与没有提示的explain()相比,带提示的explain()总是花费更少的时间。
这里回答了类似的问题 Understanding mongo db explain
答案 1 :(得分:6)
“提示”只告诉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 ,此结果在大多数情况下将与结果计数完全匹配。