如何有效地索引在执行排序时使用$ gt和$ lt的查询?

时间:2016-03-10 21:16:14

标签: mongodb indexing

我正在尝试使用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,
  1. 它使用66156 nscannedObjects
  2. 评估每个文档
  3. 即使所有字段都包含在查询
  4. 中,它也没有使用indexOnly

    我尝试删除$lt但保留$gt约束,但获得相同的结果。

    使用简单的createdAt索引更快,但会产生scanAndOrder。这是好的,因为我还是要限制查询吗?让MongoDB运行scanAndOrder与尝试使用正确的排序顺序创建索引相比要快得多,这也可以使用范围查询。只要我将限额限制在合理的数额,它可能永远不会达到内存限制?

0 个答案:

没有答案