我正在尝试使用MongoDB 2.6优化以下查询:
db.QuizResponse.find({
createdAt: {
'$lt': new Date('Thu Mar 10 2016 00:00:00 GMT-0800 (PST)'),
'$gt': new Date('Jan 1 2015 00:00:00 GMT-0800 (PST)')
}
},
{ progress: 1, createdAt: 1, _id: 0 })
.limit(0...1000) // The query will be limited in the real world
.sort({ progress: 1 })
我的第一直觉是在createdAt
上创建一个也包含progress
的索引,但是我遇到scanAndOrder
的问题。阅读完这些文章:http://blog.mlab.com/2012/06/cardinal-ins/和https://emptysqua.re/blog/optimizing-mongodb-compound-indexes/之后,我正在尝试创建一个索引,它将为我提供最低的查询时间,而且当集合包含大量文档时,它不会成为定时炸弹。
我设置了以下索引:
{
"progress" : 1,
"createdAt" : 1
}
但是当我使用explain运行查询时,我看到了:
"cursor" : "BtreeCursor progress_createdAt",
"isMultiKey" : false,
"n" : 66156,
"nscannedObjects" : 66156,
"nscanned" : 66156,
"nscannedObjectsAllPlans" : 66156,
"nscannedAllPlans" : 66156,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 516,
"nChunkSkips" : 0,
"millis" : 272,
66156 nscannedObjects
indexOnly
醇>
我尝试删除$lt
但保留$gt
约束,但获得相同的结果。
使用简单的createdAt
索引更快,但会产生scanAndOrder
。这是好的,因为我还是要限制查询吗?让MongoDB运行scanAndOrder
与尝试使用正确的排序顺序创建索引相比要快得多,这也可以使用范围查询。只要我将限额限制在合理的数额,它可能永远不会达到内存限制?