2014-10-09 127 views
0

这种查询可以去任何更快:蒙戈聚集慢

db.foo.aggregate([ 
    {"$match": {"uid": {"$in": ["40001"]}}}, 
    { 
     "$group": { 
      "read": {"$sum": {"$cond": ["$read", 0, 1]}}, 
      "imp": {"$sum": {"$cond": ["$important", 1, 0]}}, 
      "_id": {"group_by": "$group_by", "ip_group": "$ip_group"}, 
      "date": {"$min": "$date_meta.dt"}, "count": {"$sum": 1} 
     } 
    },  
    {"$sort": {"start_time": -1}} 
]) 

在1mil的〜。如果uid =“40001”(大约900000 - 90%的集合)对于其他所有uid聚合来说要快得多,则大约需要2,3秒。所以看起来mongo花费大部分时间来减少结果。 我厌倦了删除条件陈述,但没有获得任何速度。所以看起来好像什么都不能做,但我可能在某个地方忽略了这一点。 哦,我尝试了索引,并删除$排序选项,但没有改进。

+1

$ sort没有效果,因为$ group stage没有字段** start_time **,否则会变慢。我认为这取决于** $ group **舞台上的团体数量;如果** $ group **的** _ id **是一个常数(最后只有一组),我想这对您来说是极端的速度。顺便说一下,700MB还需要从磁盘读取一些时间。 – Wizard 2014-10-09 14:31:48

+0

不mongo通过mmap()保存内存中的所有记录吗?我不认为每次阅读后都会刷新所有数据,否? – dakt 2014-10-09 15:49:42

+0

你说得对。它在第一次读取后被缓冲。 – Wizard 2014-10-10 00:51:06

回答

1

如果MongoDB需要将大量文档加载到内存中(900,000是一个很好的数量),这将需要一些时间。改善这个问题的方法是...

  • 改善硬件
  • 使用分片来分配负载

拆分将工作做好,如果组显著减少文件的数量。这是因为最初的小组工作将在每个碎片上完成,然后在MongoS上重新完成。

+0

改进硬件意味着什么?收集的大小是由db.collection.stats()报告的705695808字节。所以有足够的内存和机器运行4个CPU。现在我可以做平行的工作?如果这甚至是可能的?也许通过使用$ out并汇总最终的集合?分片也不是ATM的选项。 – dakt 2014-10-09 14:08:10

+0

我的意思是,这是导致搜索速度缓慢的一件事。如果你有一个关于'uid'的索引,除了我的建议之外,没有其他任何事情可以做,而不需要重新组织数据。 '$ out'会让检索结果变慢。 – 2014-10-09 15:47:50