12

我知道使用.explain()MongoDB 查询的输出,您可以查看 和 之间的区别nnscanned以确定是否已执行完整集合扫描,或者是否已使用索引。文档状态

您希望nnscanned尽可能接近价值。

凯尔·班克 (Kyle Banker) 的优秀著作 MongoDB in Action说了类似的话:

一般来说,您希望 和 的值n尽可能nscanned接近。在进行集合扫描时,几乎不会出现这种情况。

显然,这些陈述都不是关于比较n和的确定性nscanned。什么比例的差异通常可以推断出完整的集合扫描 - 10%、20%、30%+?是否有任何其他方法可以检查是否已完成完整的收藏扫描?

4

5 回答 5

26

上面的答案并不完全正确。

在使用索引进行排序但不能帮助匹配标准的情况下,还将执行集合扫描。在这种情况下,将扫描所有文档(按索引顺序)以查找符合查找条件的文档。另一种可能性是可能存在部分集合扫描,其中索引能够根据一个或多个查找条件缩小文档子集,但仍需要扫描此文档子集以查找完整查找条件的匹配项。

在这些情况下,explain 将显示正在使用的索引而不是 BasicCursor。因此,虽然在 explain 中存在 BasicCursor 表示正在执行集合扫描,但没有它并不意味着没有执行集合扫描。

此外,在使用索引进行排序的地方,使用 --notablescan 也无济于事。因为查询只会在不使用索引的情况下引发异常。它不查找索引是否用于匹配或排序。

确定是否执行集合扫描的唯一万无一失的方法是将索引键与查询中的匹配条件进行比较。如果查询优化器选择的索引(并在说明中显示)无法回答查询匹配条件(即不同的字段),则需要进行集合扫描。

于 2013-05-21T22:18:00.897 回答
7

什么比例的差异通常可以推断出完整的集合扫描 - 10%、20%、30%+?

这是不可能的,但如果它真的很重要,那么你可能会看到平均发现的性能下降高达 200%;所以是的,你会注意到的。它与这方面的任何其他数据库非常相似。

是否有任何其他方法可以检查是否已完成完整的收藏扫描?

您可以使用一个标志启动 MongoDB,告诉它永远不要进行全表扫描,在这种情况下,它会在尝试执行以下操作时抛出异常:http: //docs.mongodb.org/manual/reference/mongod/#cmdoption- mongod--显着扫描

但是最好的方法是在explain这里使用,您将知道查询何时不使用索引并被迫从磁盘或内存扫描整个集合。

于 2013-03-09T21:20:18.967 回答
1

明确的答案在 explain() 输出的第一行。

如果它说光标类型是“BasicCursor”,那么它就是一个简单的集合扫描。

否则它会说它使用什么类型的索引和索引的名称,即“BtreeCursor id

请参阅此处的文档:http: //docs.mongodb.org/manual/reference/explain/#explain-output-fields-core以获得相同的解释。

于 2013-03-09T22:19:14.503 回答
0

严格来说,似乎只有当游标是基本游标时才进行全表扫描。

如果存在 btree 游标,则可能仍然有效地进行了全表扫描以查找记录,而该 btree 索引仅用于排序。但是,如果查看 explain 的输出,您是否真的可以确定这是一次全表扫描,而无需计算记录并查看现有索引。

如果查询效率不高并且需要或应该提示更好的索引,那么在问题的上下文中会很清楚。

于 2014-08-06T15:32:59.120 回答
0

您可以检查说明的阶段(来自 MongoDB 文档):

阶段是对操作的描述;例如

-COLLSCAN 用于集合扫描
-IXSCAN 用于扫描索引键
-FETCH 用于检索文档
-SHARD_MERGE 用于合并来自分片的结果

于 2015-09-19T06:35:14.040 回答