MongoDB管道优化

官网资料:$sort

其它资料:聚合管道优化

$match + $project

当管道的顺序为 $project → $match 时,优化器会将 $match 提前到 $project 前面去执行。

例如,管道包括如下阶段:

{ $project: { status: 1, name: 1 } },
{ $match: { age : 18 } }

优化器优化后,会变成:

{ $match: { age : 18 } },
{ $project: { status: 1, name: 1 } }

类似的操作包括:$match 与 $sort

$sort + $limit

当管道的顺序为 $sort → $limit 时,且中间没有修改文档数量的其它操作(如:$group、$unwind),优化器会将 $limit 合并到 $sort 中。

例如,管道包括如下阶段:

{ $sort : { age : -1 } },
{ $project : { age : 1, status : 1, name : 1 } },
{ $limit: 5 }

优化器优化后,会合并成:

{
    "$sort" : {
       "sortKey" : {
          "age" : -1
       },
       "limit" : NumberLong(5)
    }
},
{ "$project" : {
         "age" : 1,
         "status" : 1,
         "name" : 1
  }
}

这样, $sort 操作在进行时只维护前 n 个结果(也就是说得到前n个结果就停止排序),其中 n 为limit数量。当 allowDiskUse 为true并且n项超过内存限制时,此优化仍然使用 

$sort + $skip + $limit

当管道的顺序为 $sort → $skip → $limit 时,优化器会将 $limit 提前到 $skip 前面去执行,此时$limit = 优化前的$limit + 优化前的$skip。

例如,管道包括如下阶段:

{ $sort: { age : -1 } },
{ $skip: 10 },
{ $limit: 5 }

优化器优化后,会变成:

{
   "$sort" : {
      "sortKey" : {
         "age" : -1
      },
      "limit" : NumberLong(15)
   }
},
{
   "$skip" : NumberLong(10)
}

说明:当skip小时,这样分页会很快。但是当skip很大时,limit的个数还是很多,所以分页还是很慢。

$project  + $skip

当管道的顺序为 $project → $skip 时,优化器会将 $skip 提前到 $project 前面去执行。

例如,管道包括如下阶段:

{ $sort: { age : -1 } },
{ $project: { status: 1, name: 1 } },
{ $skip: 5 }

优化器优化后,会变成:

{ $sort: { age : -1 } },
{ $skip: 5 },
{ $project: { status: 1, name: 1 } }
posted @ 2022-06-20 17:00  仅此而已-远方  阅读(100)  评论(0编辑  收藏  举报