【发布时间】: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