在 $facet 中使用 $sort 和 $limit 时 Mongo 聚合速度较慢

Sta*_*ers 5 database performance mongodb wiredtiger

我注意到在看似相同的总体上存在巨大的性能差异,至少在概念上是这样。测试是在一个简单的集合结构上进行的,该结构有一个 _id、一个名称和一个createdAt,但其中有 2000 万个。在createdAt上有一个索引。它托管在 mlab 集群上,版本为 3.6.9 WiredTiger。

我正在尝试使用聚合进行简单的分页,我知道我可以使用查找和限制,但我喜欢向管道添加更多元素,我给出的示例非常精炼。

db.getCollection("runnablecalls").aggregate([
         {
          $facet: {
            docs: [
                { $sort:  {createdAt: -1} },
                { $limit:  25 },
                { $skip:  0 },                                
            ],
            page_info: [
              { $group: { _id: null, total: { $sum: 1 } } 
              }
            ],
          }
        }                           
      ])
Run Code Online (Sandbox Code Playgroud)

这几乎需要40s. 现在,如果我将$sort和移到$limit刻面之外,则需要0.042s.

db.getCollection("runnablecalls").aggregate([
        { $sort:  {createdAt: -1} },
        { $limit:  25 }, 
        {
          $facet: {
            docs: [           
                { $skip:  0 },                
            ],            
            page_info: [
                { 
                  $group: { _id: null, total: { $sum: 1 } } 
                } 
            ]}
        },                           
      ])
Run Code Online (Sandbox Code Playgroud)

page_info最后的刻面没有什么区别,我可以毫无区别地把它拿出来,我只是把它留在里面,因为我喜欢用它。我知道如何使用两个查询(一个计数和一个聚合)来解决问题,而无需$facet. 我只是想了解为什么会发生这种情况。

sim*_*gix 2

第一个聚合不使用索引。第二个聚合使用索引并在进入之前过滤前 25 个文档$facet。您可以添加explain('executionStats')以查看查询计划和索引使用情况。例如,

db.getCollection("runnablecalls").explain('executionStats').aggregate([
         {
          $facet: {
            docs: [
                { $sort:  {createdAt: -1} },
                { $limit:  25 },
                { $skip:  0 },                                
            ],
            page_info: [
              { $group: { _id: null, total: { $sum: 1 } } 
              }
            ],
          }
        }                           
      ])
Run Code Online (Sandbox Code Playgroud)