我有一个查询,通常需要大约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
表示查询在运行时没有等待锁定,或者同时有任何其他查询在运行。
答案 0 :(得分:0)
对我来说,您的查询似乎有错误的索引:{ 'followed_by': -1, 'age': -1 }
。您应该有一个索引{ 'followers': 1}
(但要考虑该字段的基数)。但是即使有了该索引,您仍需要进行inmem排序。无论如何,以高基数的方式应该更快一些,因为您将不需要像使用索引前缀followed_by
一样扫描整个集合以进行过滤步骤。