额外的" nscanned"来自这个.explain()?

时间:2015-01-27 15:45:39

标签: mongodb

我有一系列预订。每个文档都有以下字段:

_id: ObjectID, 
client: ObjectID // A reference to the "owner" of the service. 
start: nr, 
end nr

我插入了15个虚拟文档(在客户端上具有相同的ID)。前五个从1开始,到2结束,接下来五个开始于3,结束于4,最后五个开始于5并结束在6

然后我创建以下索引:db.bookings.ensureIndex({client: 1, start: 1, end: 1})

对于这些查询:

db.bookings.find({client: anID, start: {$gte: 1}}).explain()
db.bookings.find({client: anID, start: {$gte: 3}}).explain()
db.bookings.find({client: anID, start: {$gte: 5}}).explain()

我按顺序得到了这些预期的结果:

"n": 15, "nscannedObjects": 15, "scanned": 15
"n": 10, "nscannedObjects": 10, "scanned": 10
"n": 5, "nscannedObjects": 5, "scanned": 5

这是预期的,完全没问题。

但在进行这些查询时:

db.bookings.find({client: anID, start: {$gte: 1}, end: {$lte: 2}}).explain()
db.bookings.find({client: anID, start: {$gte: 3}, end: {$lte: 4}}).explain()
db.bookings.find({client: anID, start: {$gte: 5}, end: {$lte: 6}}).explain()

我按顺序得到了这些令人困惑的结果:

"n": 5, "nscannedObjects": 5, "scanned": 7
"n": 5, "nscannedObjects": 5, "scanned": 6
"n": 5, "nscannedObjects": 5, "scanned": 5

为什么我在前两个查询中获得额外的(预期5个)扫描文档?我的索引或查询中有什么问题吗?

2 个答案:

答案 0 :(得分:2)

nscanned计数可能高于nscannedObjects计数,因为MongoDB扫描了特定对象/文档的多个索引条目,然后进行了重复数据删除。这实际上是文档中explain example的一部分。对于复合键,也可能是索引条目被扫描的情况,因为它匹配最左边的字段(例如),但因为它在其他字段之一上不匹配,所以文档被跳过而不扫描

excellent post herebtree遍历的视觉效果,有助于了解这种情况如何发生。

另外,版本3.0中新版本的说明会将这些字段替换为totalKeysExaminedtotalDocsExamined。它们代表着相同的东西,但名称更能说明它们实际代表的含义。

答案 1 :(得分:1)

如果在没有关系的情况下查询两个范围,就像我上面那样。 (开始和结束)我发现this great tip关于"关闭"查询中的第一个范围。在封闭的第一个范围内,查询将有更好的表现。