【问题标题】:MySQL Vs MongoDB aggregation performanceMySQL 与 MongoDB 的聚合性能
【发布时间】:2013-12-15 16:30:35
【问题描述】:

我目前正在为我的应用程序测试一些数据库。主要功能是数据聚合(类似于这里的这个人:Data aggregation mongodb vs mysql)。

我也面临同样的问题。我创建了一个示例测试数据。 mysql 端没有连接,它是一个单一的 innodb 表。这是一个 160 万行的数据集,我正在对整个表进行求和和计数,没有任何过滤器,因此我可以比较每个聚合引擎的​​性能。在这两种情况下,所有数据都适合内存。在这两种情况下,都没有写入负载。

使用 MySQL (5.5.34-0ubuntu0.12.04.1) 我总是在 2.03 和 2.10 秒左右得到结果。 使用 MongoDB(2.4.8,linux 64 位)我得到的结果总是在 4.1 到 4.3 秒之间。

如果我对索引字段进行一些过滤,MySQL 结果时间会下降到 1.18 和 1.20 左右(处理的行数正好下降到数据集的一半)。 如果我对 MongoDB 上的索引字段进行相同的过滤,结果时间仅下降到 3.7 秒左右(再次处理一半的数据集,我通过对匹配条件的解释确认了这一点)。

我的结论是: 1) 我的文件设计得非常糟糕(确实可以),或者 2) MongoDB 聚合框架确实不符合我的需求。

问题是:我可以做些什么(在特定的 mongoDB 配置、文档建模等方面)以使 Mongo 的结果更快?这是MongoDB不适合的情况吗?

我的表格和文档架构:

| events_normal |

CREATE TABLE `events_normal` (
  `origem` varchar(35) DEFAULT NULL,
  `destino` varchar(35) DEFAULT NULL,
  `qtd` int(11) DEFAULT NULL,
  KEY `idx_orides` (`origem`,`destino`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |

{
    "_id" : ObjectId("52adc3b444ae460f2b84c272"),
    "data" : {
        "origem" : "GRU",
        "destino" : "CGH",
        "qtdResultados" : 10
    }
}

提到的索引和过滤字段是“origem”和“destino”。

select sql_no_cache origem, destino, sum(qtd), count(1) from events_normal group by origem, destino;
select sql_no_cache origem, destino, sum(qtd), count(1) from events_normal where origem="GRU" group by origem, destino;

db.events.aggregate( {$group: {         _id: {origem: "$data.origem", destino: "$data.destino"},         total: {$sum: "$data.qtdResultados" },         qtd: {$sum: 1}     }  } )
db.events.aggregate( {$match: {"data.origem":"GRU" } } , {$group: {         _id: {origem: "$data.origem", destino: "$data.destino"},         total: {$sum: "$data.qtdResultados" },         qtd: {$sum: 1}     }  } )

谢谢!

【问题讨论】:

  • 聚合框架目前不如旧的 SQL(以一种很好的方式)并且在并行线程等方面非常成熟,但是在接下来的几个版本中会有很多改进,不过超过 4 秒,您的意思是像 6 秒或 7 秒,还是仅仅 4.01 秒?
  • @Sammaye 抱歉没有具体说明:大约是 4.1 秒,有时是 4.3 秒。我已经更正了这个问题。

标签: mysql mongodb performance aggregation-framework


【解决方案1】:

聚合并不是 MongoDB 最初设计的目的,因此它并不是真正的最快功能。

当你真的想使用 MongoDB 时,你可以使用分片,这样每个分片都可以处理它在聚合中的份额(确保选择 shard-key 的方式是每个组只在一个集群上,否则你会达到相反的效果)。然而,这不再是与 MySQL 的公平比较,因为 MongoDB 集群将使用更多的硬件。

【讨论】:

  • 嗨菲利普,感谢您的回答!在这种情况下,我也可以使用 MySQL Cluster 对 MySQL 表进行分片,理论上可以获得更快的结果,对吧?
  • @MarcosViníciusdaSilva 也许吧。我从未使用过 MySQL 分片。 MongoDB 是从一开始就为分片而设计的,而 MySQL 是在事后才添加分片的,所以我认为 MongoDB 的利润更高,但这只是我的估计,没有任何经验或事实支持。
  • 感谢您的回答。我得出的结论是,我需要使用更详细的策略来快速在任何数据库中保持结果。
猜你喜欢
  • 1970-01-01
  • 2015-02-17
  • 1970-01-01
  • 2019-03-23
  • 1970-01-01
  • 1970-01-01
  • 2019-01-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多