签到成功

知道了

CNDBA社区CNDBA社区

MongoDB 4.4 执行计划(explain) 说明

2022-05-15 22:23 2098 0 原创 MongoDB
作者: dave

1 执行计划概述


通过执行计划我们可以观察系统如何使用索引来加快检索,同时可以做针对性的性能优化。http://www.cndba.cn/cndba/dave/article/108007http://www.cndba.cn/cndba/dave/article/108007

explain结果将查询计划以阶段树的形式呈现。每个阶段将其结果(文档或索引键)传递给父节点。叶节点访问集合或索引。中间节点操纵有子节点产生的文档或索引建。根节点是mongodb从中派生结果集的最后阶段。

在MongoDB 中,可以通过explain命令来查看其它命令的执行信息,比如:aggregate, count, distinct, find, findAndModify, delete, mapReduce, update。

示例:

db.runCommand(
   {
     explain: { count: "products", query: { quantity: { $gt: 50 } } },
     verbosity: "queryPlanner"
   }
)

Explain命令的详细说明可以参考官方手册:

https://www.mongodb.com/docs/v4.4/reference/command/explain/http://www.cndba.cn/cndba/dave/article/108007

虽然可以使用explain 命令来查看执行计划,但是MongoDB 官方更建议使用db.collection.explain() 和cursor.explain()方法来查看执行计划。 本质上db.collection.explain()方法也是对explain 命令的封装。

到了MongoDB 4.4 版本,db.collection.explain() 支持的方法已经和explain命令相同。 所以可以完全替代explain 命令。

官网的说明如下:

db.collection.explain()
https://www.mongodb.com/docs/v4.4/reference/method/db.collection.explain/
cursor.explain()
https://www.mongodb.com/docs/v4.4/reference/method/cursor.explain/

2 执行计划的三种模式


db.collection.explain()方法的语法格式如下:

db.collection.explain().

比如:

db.products.explain().remove( { category: “apparel” }, { justOne: true } )

也可以通过帮助查看:http://www.cndba.cn/cndba/dave/article/108007

mongos> db.collection.explain().help()
Explainable operations
        .aggregate(...) - explain an aggregation operation
        .count(...) - explain a count operation
        .distinct(...) - explain a distinct operation
        .find(...) - get an explainable query
        .findAndModify(...) - explain a findAndModify operation
        .mapReduce(...) - explain a mapReduce operation
        .remove(...) - explain a remove operation
        .update(...) - explain an update operation
Explainable collection methods
        .getCollection()
        .getVerbosity()
        .setVerbosity(verbosity)
mongos>

mongos> db.collection.explain().find().help()
Explain query methods
        .finish() - sends explain command to the server and returns the result
        .forEach(func) - apply a function to the explain results
        .hasNext() - whether this explain query still has a result to retrieve
        .next() - alias for .finish()
Explain query modifiers
        .addOption(n)
        .batchSize(n)
        .comment(comment)
        .collation(collationSpec)
        .count()
        .hint(hintSpec)
        .limit(n)
        .maxTimeMS(n)
        .max(idxDoc)
        .min(idxDoc)
        .readPref(mode, tagSet)
        .showDiskLoc()
        .skip(n)
        .sort(sortSpec)
mongos>

db.collection.explain()方法有一个可选的参数:verbosity。该参数会影响到 explain()方法的行为和返回的信息,可以设置为如下3个值:

  1. “queryPlanner” (Default)
  2. “executionStats”
  3. “allPlansExecution”

2.1 “queryPlanner” (Default) 模式

默认情况下,db.collection.explain() 运行在queryPlanner 模式。

MongoDB通过查询优化器对待评估操作来选择最佳的查询计划(winning plan)。db.collection.explain() 返回评估方法(evaluated method)的查询计划(queryPlanner)信息。

2.2 “executionStats” 模式

MongoDB 通过查询优化器(query optimizer) 选择最佳的执行计划,然后执行该计划,待该计划执行完成后,返回描述最佳计划执行情况的统计信息。

对于写操作,db.collection.explain() 会返回待执行的update和delete 操作信息,但不会将这些修改应用到数据库。

db.collection.explain() 返回评估方法(evaluated method)的queryPlanner 和 executionStats信息。对于非最优的执行计划(rejected plans),executionStats 不会提供查询执行信息。http://www.cndba.cn/cndba/dave/article/108007

2.3 “allPlansExecution” 模式

MongoDB 通过查询优化器(query optimizer) 选择最佳的执行计划,然后执行该计划。 在allPlansExecution 模式下,MongoDB 除了返回描述最佳计划执行情况的统计信息,还返回在计划选择期间捕获的其他候选计划的统计信息。 http://www.cndba.cn/cndba/dave/article/108007

同样,对于写操作,db.collection.explain() 会返回待执行的update和delete 操作信息,但不会将这些修改应用到数据库。

db.collection.explain() 返回评估方法(evaluated method)的queryPlanner 和 executionStats信息。对于最优执行计划(winning plan),executionStats包含完整的查询执行信息。 http://www.cndba.cn/cndba/dave/article/108007

如果查询优化器分析了多个计划,executionStats信息还包括计划选择阶段最优计划和非最优计划的部分执行信息。

2.4 使用示例

db.products.explain().count( { quantity: { $gt: 50 } } )


db.products.explain("executionStats").find(
   { quantity: { $gt: 50 }, category: "apparel" }
)

db.products.explain("allPlansExecution").update(
   { quantity: { $lt: 1000}, category: "apparel" },
   { $set: { reorder: true } }
)

db.products.explain("executionStats").find(
   { quantity: { $gt: 50 }, category: "apparel" }
).sort( { quantity: -1 } ).hint( { category: 1, quantity: -1 } )

3 返回结果说明


返回结果官网有详细说明,可以直接查看:

Explain Results
https://www.mongodb.com/docs/v4.4/reference/explain-results/

这里主要需要关注4个选项:http://www.cndba.cn/cndba/dave/article/108007

  1. “nReturned” : 查询条件匹配到的文档数量,即操作返回的数据量。
  2. “executionTimeMillisEstimate” : 查询计划所需的总时间(毫秒为单位)
  3. “totalKeysExamined” : 扫描的索引项数(索引扫描条目)。
  4. “totalDocsExamined” : 扫描的文档数,而不是返回的文档数。如果在查询执行期间多次检查文档,则totalDocsExamined会对每次检查进行计数。也就是说,totalDocsExamined不是检查的唯一文档总数的计数。

检查文档常用的查询执行阶段是COLLSCAN和FETCH。

执行计划中stage的类型如下:

http://www.cndba.cn/cndba/dave/article/108007

  1. COLLSCAN:全表扫描
  2. IXSCAN:索引扫描
  3. FETCH:根据索引去检索指定document
  4. SHARD_MERGE:将各个分片返回数据进行merge
  5. SORT:表明在内存中进行了排序
  6. LIMIT:使用limit限制返回数
  7. SKIP:使用skip进行跳过
  8. IDHACK:针对_id进行查询
  9. SHARDING_FILTER:通过mongos对分片数据进行查询
  10. COUNT:利用db.coll.explain().count()之类进行count运算
  11. COUNTSCAN:count不使用Index进行count时的stage返回
  12. COUNT_SCAN:count使用了Index进行count时的stage返回
  13. SUBPLA:未使用到索引的$or查询的stage返回
  14. TEXT:使用全文索引进行查询时候的stage返回
  15. PROJECTION:限定返回字段时候stage的返回

对于普通查询,希望看到stage的组合(查询的时候尽可能用上索引):

  1. Fetch + IDHACK
  2. Fetch + ixscan
  3. Limit+(Fetch + ixscan)
  4. PROJECTION + ixscan
  5. SHARDING_FITER + ixscan
  6. COUNT_SCAN

不希望看到包含如下的stage:

  1. COLLSCAN(全表扫描)
  2. SORT(使用sort但是无index)
  3. 不合理的SKIP,SUBPLA(未用到index的$or)
  4. COUNTSCAN(不使用index进行count)

更多案例可以参考:http://www.cndba.cn/cndba/dave/article/108007

https://blog.csdn.net/mijichui2153/article/details/115680742

版权声明:本文为博主原创文章,未经博主允许不得转载。

用户评论
* 以下用户言论只代表其个人观点,不代表CNDBA社区的观点或立场
dave

dave

关注

人的一生应该是这样度过的:当他回首往事的时候,他不会因为虚度年华而悔恨,也不会因为碌碌无为而羞耻;这样,在临死的时候,他就能够说:“我的整个生命和全部精力,都已经献给世界上最壮丽的事业....."

  • 2296
    原创
  • 3
    翻译
  • 582
    转载
  • 198
    评论
  • 访问:8506476次
  • 积分:4477
  • 等级:核心会员
  • 排名:第1名
精华文章
    最新问题
    查看更多+
    热门文章
      热门用户
      推荐用户
        Copyright © 2016 All Rights Reserved. Powered by CNDBA · 皖ICP备2022006297号-1·

        QQ交流群

        注册联系QQ