MongoDB——explain执行计划详解

Posted 小志的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB——explain执行计划详解相关的知识,希望对你有一定的参考价值。

目录

一、explain执行计划使用的前提条件

  • 查询是否使用了索引
  • 索引是否减少了扫描的记录数量
  • 是否存在低效的内存排序

二、explain执行计划的语法

  • explain()方法的形式

    db.collection.find().explain(<verbose>)
    
  • verbose 可选参数
    表示执行计划的输出模式,默认queryPlanner

    模式名字描述
    queryPlanner执行计划的详细信息,包括查询计划、集合信息、查询条件、最佳执行计划、查询方式和 MongoDB 服务信息等
    exectionStats最佳执行计划的执行情况和被拒绝的计划等信息
    allPlansExecution选择并执行最佳执行计划,并返回最佳执行计划和其他执行计划的执行情况

三、explain执行计划的示例

3.1、数据准备

  • 准备数据集,执行脚本

    var tags = ["nosql","mongodb","document","developer","popular"];
    var types = ["technology","sociality","travel","novel","literature"];
    var books=[];
    for(var i=0;i<50;i++)
    	var typeIdx = Math.floor(Math.random()*types.length);
    	var tagIdx = Math.floor(Math.random()*tags.length);
    	var tagIdx2 = Math.floor(Math.random()*tags.length);
    	var favCount = Math.floor(Math.random()*100);
    	var username = "xx00"+Math.floor(Math.random()*10);
    	var age = 20 + Math.floor(Math.random()*15);
    	var book = 
    		title: "book-"+i, 
    		type: types[typeIdx],
    		tag: [tags[tagIdx],tags[tagIdx2]],
    		favCount: favCount, 
    		author: name:username,age:age
    	;
    	books.push(book)
    
    db.books1.insertMany(books);
    

  • 查看初始化的数据

    db.books1.find()
    

3.2、执行explain执行计划指定queryPlanner参数

  • 未创建title的索引,执行explain指定queryPlanner参数

    db.books1.find(title:"book-1").explain("queryPlanner")
    

  • explain执行中字段的解释

    字段名称描述
    plannerVersion执行计划的版本
    namespace查询的集合
    indexFilterSet是否使用索引
    parsedQuery查询条件
    winningPlan最佳执行计划
    stage查询方式
    filter过滤条件
    direction查询顺序
    rejectedPlans拒绝的执行计划
    serverInfomongodb服务器信息

3.3、执行explain执行计划指定executionStats参数

  • executionStats 模式的返回信息中包含了 queryPlanner 模式的所有字段,并且还包含了最佳执行计划的执行情况

  • 创建title索引

    db.books1.createIndex(title:1)
    

  • 执行explain指定executionStats参数

    db.books1.find(title:"book-1").explain("executionStats")
    



  • explain执行中字段的解释

    字段名称描述
    winningPlan.inputStage用来描述子stage,并且为其父stage提供文档和索引关键字
    winningPlan.inputStage.stage子查询方式
    winningPlan.inputStage.keyPattern所扫描的index内容
    winningPlan.inputStage.indexName索引名
    winningPlan.inputStage.isMultiKey是否是Multikey。如果索引建立在array上,将是true
    executionStats.executionSuccess是否执行成功
    executionStats.nReturned返回的个数
    executionStats.executionTimeMillis这条语句执行时间
    executionStats.executionStages.executionTimeMillisEstimate检索文档获取数据的时间
    executionStats.executionStages.inputStage.executionTimeMillisEstimate扫描获取数据的时间
    executionStats.totalKeysExamined索引扫描次数
    executionStats.executionStages.isEOF是否到达 steam 结尾,1 或者 true 代表已到达结尾
    executionStats.executionStages.works工作单元数,一个查询会分解成小的工作单元
    executionStats.executionStages.advanced优先返回的结果数
    executionStats.executionStages.docsExamined文档检查数

3.4、执行explain执行计划指定allPlansExecution参数

  • allPlansExecution返回的信息包含 executionStats 模式的内容,且包含allPlansExecution:[]块

    "allPlansExecution" : [
      
        "nReturned" : <int>,
        "executionTimeMillisEstimate" : <int>,
        "totalKeysExamined" : <int>,
        "totalDocsExamined" :<int>,
        "executionStages" : 
         	"stage" : <STAGEA>,
         	"nReturned" : <int>,
         	"executionTimeMillisEstimate" : <int>,
         	...
         	
        
      ,
      ...
    ]
    

3.5、 stage状态

状态描述
COLLSCAN全表扫描
IXSCAN索引扫描
FETCH根据索引检索指定文档
SHARD_MERGE将各个分片返回数据进行合并
SORT在内存中进行了排序
LIMIT使用limit限制返回数
SKIP使用skip进行跳过
IDHACK对_id进行查询
SHARDING_FILTER通过mongos对分片数据进行查询
COUNTSCANcount不使用Index进行count时的stage返回
COUNT_SCANcount使用了Index进行count时的stage返回
SUBPLA未使用到索引的$or查询的stage返回
TEXT使用全文索引进行查询时候的stage返回
PROJECTION限定返回字段时候stage的返回

3.6、执行计划的返回结果中尽量不要出现以下stage

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

以上是关于MongoDB——explain执行计划详解的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB执行计划分析详解

Explain执行计划详解

Hive底层原理:explain执行计划详解

MySQL 执行计划explain详解

mysql 执行计划explain详解

MySQL 的执行计划 explain 详解