我有一系列预订。每个文档都有以下字段:
_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个)扫描文档?我的索引或查询中有什么问题吗?
答案 0 :(得分:2)
nscanned
计数可能高于nscannedObjects
计数,因为MongoDB扫描了特定对象/文档的多个索引条目,然后进行了重复数据删除。这实际上是文档中explain example的一部分。对于复合键,也可能是索引条目被扫描的情况,因为它匹配最左边的字段(例如),但因为它在其他字段之一上不匹配,所以文档被跳过而不扫描
excellent post here有btree
遍历的视觉效果,有助于了解这种情况如何发生。
另外,版本3.0中新版本的说明会将这些字段替换为totalKeysExamined
和totalDocsExamined
。它们代表着相同的东西,但名称更能说明它们实际代表的含义。
答案 1 :(得分:1)
如果在没有关系的情况下查询两个范围,就像我上面那样。 (开始和结束)我发现this great tip关于"关闭"查询中的第一个范围。在封闭的第一个范围内,查询将有更好的表现。