我有一个查询,对于一个有100万个文档的集合,它的运行时间通常需要30秒左右。这个查询是搜索引擎的一部分,要求每次搜索在5秒内完成。在这里用一个简化的例子(实际的docs有嵌入的文档和其他属性),假设我有以下内容。
1百万个docs 的 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
显示查询在运行时没有等待锁,或者有其他查询在同时运行。
对我来说,它看起来像你有一个不正确的索引。{ 'followed_by': -1, 'age': -1 }
对于你的查询。你应该有一个索引 { 'followers': 1}
但要考虑到该字段的基数)。但即使有了这个索引,你也需要做inmem排序。无论如何,在你有高cardinality的情况下,它应该会快得多,因为你不需要像使用索引前缀那样扫描整个集合进行过滤步骤。followed_by
.