【问题标题】:Aggregate framework can't use indexes聚合框架不能使用索引
【发布时间】:2019-06-03 20:57:01
【问题描述】:

我运行这个命令:

db.ads_view.aggregate({$group: {_id : "$campaign", "action" : {$sum: 1} }});

ads_view : 500 000 个文档。

这个查询需要 1.8s 。这是它的简介:https://gist.github.com/afecec63a994f8f7fd8a

索引:db.ads_view.ensureIndex({campaign: 1});

但是 mongodb 不使用索引。任何人都知道是否可以聚合框架使用索引,如何索引这个查询。

【问题讨论】:

    标签: mongodb indexing


    【解决方案1】:

    这是一个迟到的答案,但由于 Mongo 4.0 版中的 $group 仍然不会使用索引,它可能对其他人有帮助。

    要显着加快聚合速度,请在 $group 之前执行 $sort

    所以你的查询会变成:

    db.ads_view.aggregate({$sort:{"campaign":1}},{$group: {_id : "$campaign", "action" : {$sum: 1} }});
    

    这假定在campaign 上有一个索引,它应该是根据您的问题创建的。在 Mongo 4.0 中,使用db.ads_view.createIndex({campaign:1}) 创建索引。

    我在包含 5.5+ Mio 的集合上对此进行了测试。文件。如果没有$sort,聚合数小时后也不会完成; $sort$group 之前,聚合需要几秒钟。

    【讨论】:

      【解决方案2】:

      $group 运算符不是当前将使用索引的运算符之一。这样做的运算符列表(截至 2.2)是:

      $match
      $sort
      $limit
      $skip
      

      从这里开始:

      http://docs.mongodb.org/manual/applications/aggregation/#pipeline-operators-and-indexes

      根据 gist 中发生的产量数量,我假设您有一个非常活跃的实例,或者当您进行分组时,很多这些数据不在内存中(它通常会在页面错误时产生太),因此是 1.8 秒

      请注意,即使 $group 可以使用索引,并且您的索引涵盖了所有被分组的内容,它仍然需要对索引进行全面扫描以进行分组,而且速度可能不会太快。

      【讨论】:

      • 不,组不会使用索引。我不确定您是否看到了我添加的注释 - 在这里使用索引不一定有优势 - 您只是将表扫描切换为完整索引扫描。
      【解决方案3】:

      $group 不使用索引,因为它没有必要。当您$group 您的项目时,您实际上是在使用您的$group_id 索引通过管道的$group 阶段的所有文档。如果您使用与$group_id 匹配的索引,您仍然需要遍历索引中的所有文档,因此工作量相同。

      【讨论】:

        猜你喜欢
        • 2013-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-11
        • 2015-10-31
        • 1970-01-01
        • 2014-09-03
        • 2020-04-08
        相关资源
        最近更新 更多