我有一个名为MongoDB的集合post
与3500万级的对象.该集合有两个二级索引,定义如下.
> db.post.getIndexKeys() [ { "_id" : 1 }, { "namespace" : 1, "domain" : 1, "post_id" : 1 }, { "namespace" : 1, "post_time" : 1, "tags" : 1 // this is an array field } ]
我希望以下查询,只需过滤namespace
和post_time
,在合理的时间内运行而不扫描所有对象.
>db.post.find({post_time: {"$gte" : ISODate("2013-04-09T00:00:00Z"), "$lt" : ISODate("2013-04-09T01:00:00Z")}, namespace: "my_namespace"}).count() 7408
然而,MongoDB需要至少十分钟来检索结果,奇怪的是,它设法根据功能扫描7000万个对象来完成工作explain
.
> db.post.find({post_time: {"$gte" : ISODate("2013-04-09T00:00:00Z"), "$lt" : ISODate("2013-04-09T01:00:00Z")}, namespace: "my_namespace"}).explain() { "cursor" : "BtreeCursor namespace_1_post_time_1_tags_1", "isMultiKey" : true, "n" : 7408, "nscannedObjects" : 69999186, "nscanned" : 69999186, "nscannedObjectsAllPlans" : 69999186, "nscannedAllPlans" : 69999186, "scanAndOrder" : false, "indexOnly" : false, "nYields" : 378967, "nChunkSkips" : 0, "millis" : 290048, "indexBounds" : { "namespace" : [ [ "my_namespace", "my_namespace" ] ], "post_time" : [ [ ISODate("2013-04-09T00:00:00Z"), ISODate("292278995-01--2147483647T07:12:56.808Z") ] ], "tags" : [ [ { "$minElement" : 1 }, { "$maxElement" : 1 } ] ] }, "server" : "localhost:27017" }
对象数量和扫描次数之间的差异必须由标签阵列的长度(均等于2)引起.不过,我不明白为什么post_time
过滤器不使用索引.
你能告诉我我可能会缺少什么吗?
(我正在使用24核和96 GB RAM的下降机.我使用的是MongoDB 2.2.3.)