提问者:小点点

分组前排序是否可以使用聚合框架在Mongo中提高查询性能?


我正在尝试汇总14-15个月期间100个帐户的数据,按年份和月份分组。

然而,查询性能很差,因为它需要22-27秒。目前集合中有超过1500万条记录,我有一个匹配条件的索引,可以使用解释()看到优化器使用它。

我尝试在下面的查询中的排序条件上添加另一个索引,添加索引后,查询现在需要超过50秒!即使我从查询中删除排序后也会发生这种情况。

我非常困惑。我认为因为分组不能利用索引,如果集合事先排序,那么分组可能会快得多。这个假设正确吗?如果不是,我还有什么其他选择?我可以忍受查询性能高达5秒,但仅此而已。

//Document Structure
{
    Acc: 1,
    UIC: true,
    date: ISODate("2015-12-01T05:00:00Z"),
    y: 2015
    mm: 12
    value: 22.3 
}

//Query
db.MyCollection.aggregate([
    { "$match" : { "UIC" : true, "Acc" : { "$in" : [1, 2, 3, ..., 99, 100] }, "date" : { "$gte" : ISODate("2015-12-01T05:00:00Z"), "$lt" : ISODate("2017-02-01T05:00:00Z") } } }, 
    //{ "$sort" : { "UIC" : 1, "Acc" : 1, "y" : -1, "mm" : 1 } }, 
    { "$group" : { "_id" : { "Num" : "$Num", "Year" : "$y", "Month" : "$mm" }, "Sum" : { "$sum" : "$value" } } }
])

共1个答案

匿名用户

我建议您做的是制作一个脚本(可以在nodejs中),将数据聚合在不同的集合中。当您有这些长查询时,建议您制作一个包含聚合数据的不同集合并从中进行查询。

我的第二个建议是在这个聚合集合中创建一个组合索引,并通过正则表达式进行搜索。在您的情况下,我会创建一个包含的索引,例如,对于帐户1和2016年2月,索引将类似于1:201602

然后您将能够使用按帐户和时间戳的正则表达式执行查询。就像您想要帐户1的2016年寄存器一样,您可以执行以下操作:

找到{_id:\1:2016\})

希望我的回答有帮助