我了解在MongoDB查询中使用.explain()
的输出,您可以查看n
和nscanned
之间的差异,以确定是否已执行完整的集合扫描,或者如果已使用索引。 The docs州
您希望
n
和nscanned
尽可能接近值。
Kyle Banker's excellent book MongoDB in Action说的非常相似:
一般来说,您希望
n
和nscanned
的值尽可能接近。在进行收集扫描时,几乎不会出现这种情况。
显然,这些陈述都不是关于比较n
和nscanned
的确定性。差异的比例通常推断完整的收集扫描 - 10%,20%,30%+?有没有其他方法可以检查是否已完成完整的收集扫描?
答案 0 :(得分:25)
上述答案并不完全正确。
还将执行集合扫描,其中索引用于排序但无法辅助匹配条件。在这种情况下,扫描所有文档(按索引顺序)以查找与查找条件匹配的文档。另一种可能性是可能存在部分收集扫描,其中索引能够根据一个或多个查找条件缩小文档子集,但仍需要扫描此文档子集以查找完整查找条件的匹配。
在这些情况下,explain将显示正在使用的索引,而不是BasicCursor。因此,虽然BasicCursor在解释中的存在表明正在执行集合扫描,但缺少它并不意味着没有执行集合扫描。
此外,使用--notablescan也无法帮助索引用于排序。因为查询仅引发未使用索引的异常。它不会查找索引是用于匹配还是排序。
确定是否执行了集合扫描的唯一简单方法是将索引键与查询中的匹配条件进行比较。如果查询优化器选择的索引(并在解释中显示)无法回答查询匹配条件(即不同的字段),则需要进行集合扫描。
答案 1 :(得分:7)
差异的百分比通常推断完整的收集扫描 - 10%,20%,30%+?
这是不可能的,但是如果它真的很重要,那么你可能会发现平均发现的性能下降高达200%;是的,你会注意到它。它就像这方面的任何其他数据库一样。
是否有其他方法可以检查是否已完成完整的收集扫描?
您可以使用一个标志启动MongoDB,该标志告诉它永远不会进行全表扫描,在这种情况下,它会在尝试执行以下操作时抛出异常:http://docs.mongodb.org/manual/reference/mongod/#cmdoption-mongod--notablescan
然而,最好的方法是在这里使用explain
,您将知道查询何时不使用索引并被强制从磁盘或内存扫描整个集合。
答案 2 :(得分:1)
明确答案在explain()输出的第一行。
如果它说光标类型是“BasicCursor”,则它是一个简单的集合扫描。
否则它将说明它使用的索引类型和索引的名称,即。 “BtreeCursor id ”
请参阅此处的文档:http://docs.mongodb.org/manual/reference/explain/#explain-output-fields-core以获得相同的解释。
答案 3 :(得分:0)
严格来说,只有当光标是基本光标时才进行全表扫描。
如果存在btree游标,则可能仍然可以有效地进行全表扫描以查找记录,该btree索引仅用于排序。但是,如果查看解释的输出,你真的可以确定它是一个全表扫描,而不是计算记录并查看现有的索引。
在问题的上下文中,如果查询效率不高并且需要更好的索引,或者应该暗示,那么该怎么做呢。
答案 4 :(得分:0)
您可以查看解释的阶段(来自MongoDB doc):
阶段描述了操作; e.g。
-COLLSCAN用于集合扫描
-IXSCAN用于扫描索引键
-FETCH用于检索文件
-SHARD_MERGE用于合并分片的结果