MongoDB范围查询与排序 - 如何加快?

时间:2017-10-19 12:22:07

标签: mongodb sorting nosql mongodb-query query-performance

我有一个查询,通常需要大约30秒才能运行包含100万个文档的集合。此查询将构成搜索引擎的一部分,其中要求每个搜索在不到5秒的时间内完成。在这里使用简化的示例(实际的文档具有嵌入的文档和其他属性),让我们说我有以下内容:

1百万个文档Users个集合,其中每个集合如下所示:

{
  name: Dan,
  age: 30,
  followers: 400 
},
{ 
  name: Sally,
  age: 42,
  followers: 250
}
... etc

现在,让我想要返回10个用户的ID,跟随者数量在200到300之间,按年龄降序排序。这可以通过以下方式实现:

db.users.find({
  'followers': { $gt: 200, $lt: 300  },
}).
projection({ '_id': 1 }).
sort({ 'age': -1 }).
limit(10)

我创建了以下复合索引,winningPlan告诉我正在使用它:

db.users.createIndex({ 'followed_by': -1, 'age': -1 })}

但是这个查询仍然需要大约30秒,因为它必须检查数千个文档,几乎等于本案例中与查找查询匹配的文档数量。我已经尝试了不同的索引(具有不同的位置和排序顺序)而没有运气。

所以我的问题是,我还能做些什么来减少用查询检查的文档数量,或者加快必须检查文档的过程?

查询在生产和我的本地开发环境中花费了很长时间,在某种程度上决定了许多网络和硬件因素。 currentOp表示查询在运行时没有等待锁定,或者同时有任何其他查询在运行。

1 个答案:

答案 0 :(得分:0)

对我来说,您的查询似乎有错误的索引:{ 'followed_by': -1, 'age': -1 }。您应该有一个索引{ 'followers': 1}(但要考虑该字段的基数)。但是即使有了该索引,您仍需要进行inmem排序。无论如何,以高基数的方式应该更快一些,因为您将不需要像使用索引前缀followed_by一样扫描整个集合以进行过滤步骤。