【问题标题】:MongoDB's performance on aggregation queriesMongoDB 在聚合查询上的表现
【发布时间】:2010-04-08 12:56:29
【问题描述】:

在听到很多关于 MongoDB 性能的好消息后,我们决定尝试使用 Mongodb 来解决我们遇到的问题。我首先将我们在几个 mysql 数据库中的所有记录移动到 mongodb 中的单个集合中。这导致了一个包含 2900 万个文档(每个文档至少有 20 个字段)的集合,在 HD 中占用了大约 100 GB 的空间。我们决定将它们全部放在一个集合中,因为所有文档都具有相同的结构,并且我们希望查询和汇总所有这些文档的结果。

我创建了一些索引来匹配我的查询,否则即使是简单的 count() 也需要很长时间。但是,诸如 distinct() 和 group() 之类的查询仍然需要很长时间。

例子:

// creation of a compound index    
db.collection.ensureIndex({'metadata.system':1, 'metadata.company':1})

// query to get all the combinations companies and systems
db.collection.group({key: { 'metadata.system':true, 'metadata.company':true }, reduce: function(obj,prev) {}, initial: {} });

我查看了 mongod 日志,它有很多这样的行(在执行上面的查询时):

Thu Apr  8 14:40:05 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {}  bytes:1048890 nreturned:417 154ms
Thu Apr  8 14:40:08 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {}  bytes:1050205 nreturned:414 430ms
Thu Apr  8 14:40:18 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {}  bytes:1049748 nreturned:201 130ms
Thu Apr  8 14:40:27 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {}  bytes:1051925 nreturned:221 118ms
Thu Apr  8 14:40:30 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {}  bytes:1053096 nreturned:250 164ms
...
Thu Apr  8 15:04:18 query database.$cmd ntoreturn:1 command  reslen:4130 1475894ms

这个查询花费了 1475894 毫秒,这比我预期的要长得多(结果列表大约有 60 个条目)。首先,考虑到我收藏的大量文档,这是预期的吗?一般来说,聚合查询在 mongodb 中会这么慢吗?关于如何提高性能的任何想法?

我在具有双核和 10GB 内存的单机上运行 mongod。

谢谢。

【问题讨论】:

  • 嗯,这个问题太老了,当您搜索 MongoDB 聚合框架时,仍然会出现在搜索引擎中。马里奥你没有提到你的 MongoDB 版本,因为他们在 2.4 中改进了很多 AF,而我正在一个蹩脚的 m1 上做这件事。 EC2 在 69m 的集合上拥有 3.7G 内存,并且比以前快得多。您是否尝试过新版本或采用了不同的方法?当然,AF 与 MapReduce 有大量基准测试,但请看一下来自 10Gen blog.mongodb.org/post/62900213496/…tnx 的最新基准测试
  • 感谢您的评论。那是在 2010 年,我相信我们使用的是 MongoDB 1.4.0 之类的东西。已经有一段时间了,我确信从那以后 mongodb 发生了很多变化,但是从那年晚些时候我就没有在那个项目中工作了 :)
  • 感谢马里奥的回复。我刚开始使用 MongoDB(大约一年),只是想看看你的项目发生了什么。还是祝你好运:)

标签: performance mongodb


【解决方案1】:

这个想法是通过在分布在多台机器上的分片数据库上使用 MapReduce 来提高聚合查询的性能。

我在同一台机器上对 Mongo 的 Mapreduce 与 Oracle 中的 group-by-select 语句的性能进行了一些比较。我确实发现 Mongo 慢了大约 25 倍。这意味着我必须在至少 25 台机器上对数据进行分片,才能在 Mongo 中获得与 Oracle 在单台机器上提供的相同的性能。我使用了一个包含大约 1400 万个文档/行的集合/表。

通过 mongoexport.exe 从 mongo 导出数据并将导出的数据用作 Oracle 中的外部表并在 Oracle 中进行分组比使用 Mongo 自己的 MapReduce 快得多。

【讨论】:

  • 知道哪个版本的MongoDB真的很有帮助。
  • 我相信它类似于 1.4.0 版。这是在 2010 年。
【解决方案2】:

几件事。

1) 您的组查询正在处理 很多 数据。虽然您的结果集很小,但看起来它正在对集合中的所有数据进行表格缩放以生成那个小结果。这可能是缓慢的根本原因。为了加快速度,您可能希望在查询运行时通过 iostat 查看服务器的磁盘性能,因为这可能是瓶颈。

2)正如在其他答案中所指出的,group 命令使用 javascript 解释器,这将限制性能。您可以尝试使用在 2.1 中作为测试版发布的新聚合框架(注意:这是截至 2012 年 2 月 24 日的不稳定版本)。请参阅http://blog.mongodb.org/post/16015854270/operations-in-the-new-aggregation-framework 以获得很好的介绍。这不会克服(1)中的数据量问题,但它是用 C++ 实现的,如果 javascript 时间是瓶颈,那么它应该快得多。

3) 另一种方法是使用增量 map-reduce 生成带有分组结果的第二个集合。这个想法是,您将运行一次 map-reduce 作业来聚合您的结果,然后定期运行另一个 map-reduce 作业,将新数据重新减少到现有集合中。然后,您可以从您的应用程序中查询第二个集合,而不是每次都运行一个组命令。

【讨论】:

    【解决方案3】:

    聚合(map reduce 或其他)在 mongo 中非常慢,因为它是由 javascript VM 完成的,而不是数据库引擎。对于时间序列数据,这仍然是这个(非常好,imo)数据库的限制。

    【讨论】:

    猜你喜欢
    • 2017-04-04
    • 2019-06-18
    • 1970-01-01
    • 1970-01-01
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    相关资源
    最近更新 更多