mongodb统计500万doc太慢了

时间:2016-07-14 03:29:32

标签: mongodb performance aggregation-framework

500万mongo doc:

{
    _id: xxx,
    devID: 123,
    logLevel: 5,
    logTime: 1468464358697
}

索引:     DEVID

我的聚合:

[
    {$match: {devID: 123}},
    {$group: {_id: {level: "$logLevel"}, count: {$sum: 1}}}
]

汇总结果:

{ "_id" : { "level" : 5 }, "count" : 5175872 }
{ "_id" : { "level" : 1 }, "count" : 200000 }

汇总解释:

numYields:42305
29399ms

问: 如果mongo没有写入(保存)数据,则需要29秒     如果mongo正在写(保存)数据,则需要2分钟     我的汇总结果需要回复网页,所以29秒或2分钟太长了     我怎么解决呢?优选10秒或更短     谢谢大家

1 个答案:

答案 0 :(得分:0)

在您的示例中,{devID: 123, logLevel:5}的聚合查询返回5,175,872的计数,看起来它计算了集合中的所有文档(因为您提到了您有500万个文档)。

在这个特定的例子中,我猜测{$match: {devID: 123}}阶段几乎匹配每个文档,因此聚合正在进行基本上是一个集合扫描。根据您的RAM大小,这可能会导致您的工作集推出内存,并减慢服务器正在执行的每个其他查询的速度。

如果您无法为$match阶段提供更具选择性的标准(例如,使用一系列logTime以及devID),那么预先汇总的报告可能是您的最佳选择。

一般而言,预聚合报告是包含所需聚合信息的文档,每次插入相关集合时都会更新此文档。例如,您可以在单独的集合中包含单个文档,如下所示:

{log:
    {devID: 123,
    levelCount: [
        {level: 5, count: 5175872},
        {level: 1, count: 200000}
    ]
}}

每次插入日志集时,都会使用相关详细信息更新该文档。

使用预先聚合的报告,您不再需要运行聚合查询。相反,您可以使用单个find()查询来获取所需的汇总信息。

有关预先汇总报告的更多示例,请参阅https://docs.mongodb.com/ecosystem/use-cases/pre-aggregated-reports/