【发布时间】:2017-09-20 15:54:35
【问题描述】:
我有一个包含数百万条记录的日志集合。创建新索引需要“永远”。所以最好使用现有的索引。
现在我想获取某些错误代码的出现次数。我使用这个查询,并且在功能上它工作正常:
db.getCollection('logs.res').aggregate([
{
$match:{
timeStamp: {
$gte: new Date('2017-05-01').getTime(), // timeStamp is Number
$lt : new Date('2017-05-02').getTime() // of ms since epoch
},
'objData.@.ErrorCode': {
$ne: null
}
}
},
{
$group: {
_id: '$objData.@.ErrorCode',
count: {$sum: 1}
}
},
{
$sort: { count: -1}
}
]);
问题在于,仅仅执行一天就需要将近 10 秒。我假设将使用以下索引:timeStamp_-1_objData.@.ErrorCode_1:
{
"timeStamp" : -1,
"objData.@.ErrorCode" : 1
}
然而,MongoDB 似乎坚持使用一些 timeStamp: 1 索引(以及与查询无关的一些其他索引),并扫描所有结果以查看某些响应是否可能附加了 ErrorCode,即使这些信息应该是在索引中。
这里是explain():
-
有没有办法使用
timeStamp_-1_objData.@.ErrorCode_1索引 来加快速度? - 为什么不使用这个索引?我可能误解了这个查询是如何使用索引的。
在 OSX 上运行 MongoDB 3.2.7。
注意:我也试过用$empty: true 代替$ne: null。它产生相同的结果,但有人说如果你想使用复合索引,你不能使用$empty。不过,有关 Stack Overflow 的许多问题都是旧的(mongo 2.x)。
【问题讨论】:
标签: mongodb indexing compound-index