我有一个集合"活动"与模特:
{
_id: ObjectId,
action: String,
userId: ObjectId,
time: Date
}
我有一个问题:
db.activities.find({
action: {
$in: [
"1stAction",
"2ndAction",
...,
"20thAction",
]
},
userId: {
$in: [
ObjectId("1stUserId"),
ObjectId("2ndUserId"),
...,
ObjectId("500thUserId"),
]
},
time: {
$lt: new Date()
}
}).sort({
time: -1
}).limit(20)
现在我有一个复合索引{userId:1,action:1,time:-1} 我保证索引不是多键的(所以它不包含数组值)。
当(actions * userIds)的计数大于200时,问题就开始了。
当count低于200时,mongodb会将每对唯一的userId +动作拆分为分离的索引覆盖查询,并在获得结果后执行SORT_MERGE子句并且完成得非常快。
当count大于200时(可以通过在mongoDB配置文件中设置 internalQueryMaxScansToExplode 选项从默认值更改),mongoDB执行查询以获取文档,并且不使用索引。所以它工作得很慢。 我不能通过推荐mongoDB团队(SERVER-24314)来增加internalQueryMaxScansToExplode设置,因为它会导致服务器崩溃。
我尝试构建另一个索引{time:-1,userId:1,action:1}但是,遗憾的是,我在集合中有太多记录,即使使用索引的查询至少需要30秒并且扫描30 000 000索引条目。这也是不可接受的。
我想在一个查询中通过20个操作和500个用户获取文档。
这个问题的最佳解决方案是什么?