我在运行的8GB linux机器上有一个mongodb。目前它处于测试模式,因此很少有其他请求进入,如果有的话。
我有一个包含100万份文件的合作项目。我在字段上创建一个索引:PeerGroup和CategoryIds(这是一个3-6个元素的数组,它将以多键生成):db.items.ensureIndex({PeerGroup:1, CategoryIds:1}
。
我在查询时
db.items.find({"CategoryIds" : new BinData(3,"xqScEqwPiEOjQg7tzs6PHA=="), "PeerGroup" : "anonymous"}).explain()
我有以下结果:
{
"cursor" : "BtreeCursor PeerGroup_1_CategoryIds_1",
"isMultiKey" : true,
"n" : 203944,
"nscannedObjects" : 203944,
"nscanned" : 203944,
"nscannedObjectsAllPlans" : 203944,
"nscannedAllPlans" : 203944,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 1,
"nChunkSkips" : 0,
"millis" : 680,
"indexBounds" : {
"PeerGroup" : [
[
"anonymous",
"anonymous"
]
],
"CategoryIds" : [
[
BinData(3,"BXzpwVQozECLaPkJy26t6Q=="),
BinData(3,"BXzpwVQozECLaPkJy26t6Q==")
]
]
},
"server" : "db02:27017"
}
我认为680ms并不是那么快。或者这可以接受吗? 另外,为什么说“indexOnly:false”?
答案 0 :(得分:5)
我认为680ms并不是那么快。或者这可以接受吗?
这取决于这些物体的大小以及这是否是第一次运行。假设您返回的整个数据集(包括索引)适合内存,那么下次运行它时它将是内存中查询,然后将基本上尽快返回。 nscanned高意味着这个查询不是很有选择性,大多数记录在PeerGroup中都有一个“匿名”值?如果是这样,并且CategoryId更具选择性,那么您可以尝试使用{CategoryIds:1, PeerGroup:1}
上的索引(使用hint()尝试相对于另一个)。
另外,为什么会说“indexOnly:false”
这只是表明您希望返回的所有字段都不在索引中,BtreeCursor
表示索引用于查询(BasicCursor意味着它没有)。要使其成为indexOnly
查询,您需要在projection中仅返回索引中的两个字段(即{_id : 0, PeerGroup:1, CategoryIds:1}
)。这意味着它永远不会触及数据本身,只能从索引中返回所需的一切。