MongoDB索引Index应用之explain()方法

  与MySQL(参考MySQL索引原理之索引分析 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com))一样,MongoDB也提供explain命令对索引进行分析。那如何使用MongoDB中的explain命令呢?下面进行实践:

  与MySQL中explain实践(参考Explain Results — MongoDB Manual)类似循环插⼊100万条数据(使用JS),不使⽤索引字段查询查看执⾏计划 ,然后给某个字段建⽴索引,使⽤索引字段作为查询条件再查看执⾏计划进⾏分析:

      

  插入200万条数据——与MySQL一样,想着MongoDB是不是也提供存储过程功能,确实提供了只是利用了JS。本以为可以参考在mongodb服务器上存储和执行 js 函数 - 存储过程 - 知乎 (zhihu.com)写存储过程insert100万条数据,但是存储过程的调用eval在MongoDB4.2以后版本就完全弃用了——官方的建议是使用事务取而代之,可以看到官网中提供的Database Command已经没有了evalDatabase Commands — MongoDB Manual,那就采取另外一种方式吧。如下:

  为后续查询分析准备不再使用默认_id,使用自定义_id,可以参考MongoDB 自动增长 | 菜鸟教程 (runoob.com)

      

       

      getNextSequence方法是通过db.system.js.insert直接放在system.js表中的。为什么是这个表而不是其他的呢?因为这个表是专门用来保存js函数的。如果定义完函数退出mongo实例,会发现还是无法使用函数getNextSequence。这是因为虽然定义了函数但是没有把函数引入仍然无法使用,也就是说每次重新进入mongo的实例后需要把相应的js函数重新导入一遍。通过,db.loadServerScripts();把system.js中的函数,引入到mongo实例

       

       

       

  下面示范explain的使用:

    

   从上图可知explain()可以接收不同的参数,通过设置不同参数我们可以查看更详细的查询计划,分别如下:

  1、queryPlannerqueryPlanner是默认参数。

      

  2、executionStatsexecutionStats会返回执⾏计划的⼀些统计信息(有些版本中和allPlansExecution等同)。

      

       

    第⼀层, executionTimeMillis最为直观explain返回值是executionTimeMillis值,指的是这条语句的执⾏时间,这个值当然是希望越少越好。其中有3executionTimeMillis,分别是:

      executionStats.executionTimeMillis query的整体查询时间。

      executionStats.executionStages.executionTimeMillisEstimate 该查询检索document获得数据的时间。

      executionStats.executionStages.inputStage.executionTimeMillisEstimate 该查询扫描⽂档 index所⽤时间。

    第⼆层, indexdocument扫描数与查询返回条⽬数 这个主要讨论3个返回项 nReturnedtotalKeysExaminedtotalDocsExamined,分别代表该条查询返回的条⽬、索引扫描条⽬、⽂档扫描条⽬。 这些都是直观地影响到executionTimeMillis,我们需要扫描的越少速度越快。 对于⼀个查询,我们最理想的状态是:nReturned=totalKeysExamined=totalDocsExamined    

    第三层, stage状态分析 那么⼜是什么影响到了totalKeysExaminedtotalDocsExamined?是stage的类型。类型列举如下:

      COLLSCAN:全表扫描
      IXSCAN:索引扫描
      FETCH:根据索引去检索指定document
      SHARD_MERGE:将各个分⽚返回数据进⾏merge
      SORT:表明在内存中进⾏了排序
      LIMIT:使⽤limit限制返回数
      SKIP:使⽤skip进⾏跳过
      IDHACK:针对_id进⾏查询
      SHARDING_FILTER:通过mongos对分⽚数据进⾏查询
      COUNT:利⽤db.coll.explain().count()之类进⾏count运算
      TEXT:使⽤全⽂索引进⾏查询时候的stage返回
      PROJECTION:限定返回字段时候stage的返回
    对于普通查询,最希望看到stage的组合(查询的时候尽可能⽤上索引)
      Fetch+IDHACK
      Fetch+IXSCAN
      Limit+Fetch+IXSCAN
      PROJECTION+IXSCAN
      SHARDING_FITER+IXSCAN
    不希望看到包含如下的stage
      COLLSCAN(全表扫描)
      SORT(使⽤sort但是⽆index)
      COUNT 不使⽤index进⾏count)

   3、allPlansExecution:allPlansExecution⽤来获取所有执⾏计划,结果参数基本与上⽂相同。其是以上两个参数的拼接。

  explain方法展示执行计划采用树结构,如图:

      

 

 

    

  

posted on 2022-03-15 15:14  池塘里洗澡的鸭子  阅读(633)  评论(0编辑  收藏  举报