MongoDB聚合查询性能改进

时间:2019-09-08 11:58:48

标签: mongodb performance indexing aggregation-framework

我最近开始将数据从Microsoft SQL Server迁移到MongoDB,以获得可伸缩性。在迁移方面一切都很好。

该文档有2个重要字段:客户,时间戳(年月日)。

我们在安装MongoDB的Azure Linux中仅导入了7500万数据。 在两个字段上都添加了复合索引之后,我们遇到了以下问题:

在3百万个数据上(过滤后),需要24秒才能完成按customerId计数的汇总组。对于相同的数据,SQL Server在不到1秒的时间内给出了结果。

您认为Casandra将是更好的解决方案吗?我们需要对大量数据的查询性能。

我尝试了磁盘写入,从而为VM提供了更多RAM。什么都没有。

查询:

aaggregate([
{ "$match" : { "Customer" : 2 } }, 
{ "$match" : { "TimestampHash" : { "$gte" : 20160710 } } }, 
{ "$match" : { "TimestampHash" : { "$lte" : 20190909 } } }, 
{ "$group" : { "_id" : { "Device" : "$Device" }, "__agg0" : { "$sum" : 1 } } }, 
{ "$project" : { "Device" : "$_id.Device", "Count" : "$__agg0", "_id" : 0 } }, 
{ "$skip" : 0 }, 
{ "$limit" : 10 }])

更新: 我使用了“ allowDiskUse:true”,问题已解决。过滤3M数据减少到4秒。

1 个答案:

答案 0 :(得分:0)

我遇到了similar problem before, during this question,说实话,我猜Cassandra在您的特定情况下会更好,但是问题是关于Mongo聚合查询优化,对吧?

就目前而言,我的一个馆藏中有超过3M +的文档,并且如果您正确地建立索引,则汇总查询不应花费24s。

  1. 首先,通过Mongo Compass检查索引使用情况。 Mongo确实在使用它吗?如果您的应用spam向数据库查询,并且index的使用量为0(如下例所示),则比您已经猜到的索引错误。 enter image description here
  2. 其次,这是使用explain方法(this doc will help you out)来检查有关query的更多信息。

  3. 第三点:索引字段排序很重要。例如,如果您的$match阶段包含3个字段,并且您按字段要求提供文档:

{ $match: {a_field:a, b_field:b, c_field:c} }

然后,您应该以完全相同的顺序在a,b,c字段上建立compound索引。

总是存在某种数据库体系结构问题。我强烈建议您不要stockpile收集一个集合中的所有数据。在插入时使用{timestamps:true}(它创建了两个字段,例如createdAt:updatedAt:

        {
            timestamps: true
        }

在您的架构中,将旧时/过期的数据存储在不同的集合中,并在确实需要使用它们时对其使用$lookup aggregation method

希望您会在我的回答中找到有用的东西。