Mar*_*lva 5 mysql performance mongodb aggregation-framework
我目前正在测试一些数据库到我的应用程序。主要功能是数据聚合(类似于这里的这个人:数据聚合 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
}
}
Run Code Online (Sandbox Code Playgroud)
提到的索引和过滤字段是“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} } } )
Run Code Online (Sandbox Code Playgroud)
谢谢!
聚合并不是 MongoDB 最初设计的目的,因此它并不是它最快的功能。
当您确实想使用 MongoDB 时,您可以使用分片,以便每个分片都可以处理其聚合份额(确保以每个组仅位于一个集群上的方式选择分片键,否则您将实现相反的结果) )。然而,这与 MySQL 的比较不再公平,因为 MongoDB 集群将使用更多的硬件。
| 归档时间: |
|
| 查看次数: |
5504 次 |
| 最近记录: |