首页 > 数据库 >提高查询效率,掌握MongoDB 4.2索引策略中的Measure Index Use技术

提高查询效率,掌握MongoDB 4.2索引策略中的Measure Index Use技术

时间:2023-04-15 22:31:56浏览次数:37  
标签:Index Use executionStats MongoDB explain 查询 索引 文档 阶段

1.使用$indexStats获取索引访问信息

使用$indexStats聚合阶段获取有关集合的每个索引的使用情况的统计信息。 例如,以下聚合操作返回有关orders集合上索引使用的统计信息:

db.orders.aggregate( [ { $indexStats: { } } ] )

提高查询效率,掌握MongoDB 4.2索引策略中的Measure Index Use技术_新功能

版本3.2中的新功能。

返回有关集合的每个索引的使用的统计信息。 如果使用访问控制运行,则用户必须具有包含indexStats操作的权限。

$indexStats阶段采用空文档,并具有以下语法:

{ $indexStats: { } }

返回文档包括以下字段:

提高查询效率,掌握MongoDB 4.2索引策略中的Measure Index Use技术_字段_02

索引的统计信息将在mongod restart或index drop and recreation上重置。

注意:在3.2.3版之前,ops字段值不包括使用索引的$match或mapReduce操作。

accesses字段报告的统计信息仅包括由用户请求驱动的索引访问。 它不包括内部操作,如通过TTL索引删除或块拆分和迁移操作。

$indexStats必须是聚合管道中的第一个阶段。

事务中不允许使用$indexStats 。

例如,集合orders包含以下文档:

{ "_id" : 1, "item" : "abc", "price" : 12, "quantity" : 2, "type": "apparel" }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "type": "electronics" }
{ "_id" : 3, "item" : "abc", "price" : 10, "quantity" : 5, "type": "apparel" }

在集合上创建以下两个索引:

db.orders.createIndex( { item: 1, quantity: 1 } )
db.orders.createIndex( { type: 1, item: 1 } )

对集合运行一些查询:

db.orders.find( { type: "apparel"} )
db.orders.find( { item: "abc" } ).sort( { quantity: 1 } )

要查看orders集合上索引使用的统计信息,请运行以下聚合操作:

db.orders.aggregate( [ { $indexStats: { } } ] )

该操作返回包含每个索引的使用情况统计信息的文档:

{
   "name" : "item_1_quantity_1",
   "key" : {
      "item" : 1,
      "quantity" : 1
   },
   "host" : "examplehost.local:27017",
   "accesses" : {
      "ops" : NumberLong(1),
      "since" : ISODate("2015-10-02T14:31:53.685Z")
   }
}
{
   "name" : "_id_",
   "key" : {
      "_id" : 1
   },
   "host" : "examplehost.local:27017",
   "accesses" : {
      "ops" : NumberLong(0),
      "since" : ISODate("2015-10-02T14:31:32.479Z")
   }
}
{
   "name" : "type_1_item_1",
   "key" : {
      "type" : 1,
      "item" : 1
   },
   "host" : "examplehost.local:27017",
   "accesses" : {
      "ops" : NumberLong(1),
      "since" : ISODate("2015-10-02T14:31:58.321Z")
   }
}

2.使用explain()返回查询计划

在executionStats模式下使用db.collection.explain()或cursor.explain()方法返回有关查询过程的统计信息,包括使用的索引,扫描的文档数以及查询处理的时间(以毫秒为单位)。

db.collection.explain()

explain结果将查询计划呈现为阶段树。

"winningPlan" : {
   "stage" : <STAGE1>,
   ...
   "inputStage" : {
      "stage" : <STAGE2>,
      ...
      "inputStage" : {
         "stage" : <STAGE3>,
         ...
      }
   }
},

每个阶段将其结果(即文档或索引键)传递给父节点。 叶节点访问集合或索引。 内部节点操纵由子节点产生的文档或索引键。 根节点是MongoDB从中派生结果集的最后阶段。

阶段描述了操作; 例如:

COLLSCAN  用于集合扫描
IXSCAN    用于扫描索引键
FETCH     用于检索文档
SHARD_MERGE      用于合并分片的结果
SHARDING_FILTER  用于从分SHARDING_FILTER过滤掉孤立文档

支持以下方法的执行计划:

提高查询效率,掌握MongoDB 4.2索引策略中的Measure Index Use技术_新功能_03

要使用db.collection.explain() ,请将上述方法之一附加到db.collection.explain() :

db.collection.explain().<method(...)>

例如:

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

查看帮助请使用:db.collection.explain().help()

db.collection.explain()具有以下参数:

提高查询效率,掌握MongoDB 4.2索引策略中的Measure Index Use技术_新功能_04

详细模式

db.collection.explain()的行为和返回的信息量取决于verbosity模式。

a.queryPlanner模式(默认)

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

MongoDB运行查询优化器 ,为评估中的操作选择获胜计划。 db.collection.explain()返回已评估方法的queryPlanner信息。

对于未加密的集合, explain返回以下queryPlanner信息:

"queryPlanner" : {
   "plannerVersion" : <int>,
   "namespace" : <string>,
   "indexFilterSet" : <boolean>,
   "parsedQuery" : {
      ...
   },
   "queryHash" : <hexadecimal string>,
   "planCacheKey" : <hexadecimal string>,
   "winningPlan" : {
      "stage" : <STAGE1>,
      ...
      "inputStage" : {
         "stage" : <STAGE2>,
         ...
         "inputStage" : {
            ...
         }
      }
   },
   "rejectedPlans" : [
      <candidate plan 1>,
      ...
   ]
}

包含查询优化器选择查询计划的信息:

explain.queryPlanner.namespace  

一个字符串,它指定运行查询的命名空间(即<database>.<collection> )。  

explain.queryPlanner. indexFilterSet

一个布尔值,指定MongoDB是否为查询形状应用了索引过滤器

explain.queryPlanner. queryHash(版本4.2中的新功能)

十六进制字符串,表示查询形状的哈希值,仅依赖于查询形状。 queryHash可以帮助识别具有相同查询形状的慢查询(包括写操作的查询过滤器)。

注意:与任何散列函数一样,两个不同的查询形状可能导致相同的散列值。 但是,不太可能在不同查询形状之间发生散列冲突。

有关queryHash和planCacheKey更多信息,请参阅queryHash和planCacheKey 。

explain.queryPlanner. planCacheKey(版本4.2中的新功能)

与查询关联的计划缓存条目的密钥的哈希。

与queryHash不同,planCacheKey是查询形状和该形状的当前可用索引的函数。 也就是说,如果添加/删除可支持查询形状的索引,则planCacheKey值可能会更改,而queryHash值不会更改。  

有关queryHash和planCacheKey更多信息,请参阅queryHash和planCacheKey 。  

explain.queryPlanner. winningPlan 

详细说明查询优化程序选择的计划的文档。 MongoDB将计划呈现为阶段树; 即一个阶段可以有一个inputStage或者,如果舞台有多个子阶段,则可以有inputStages 。  

explain.queryPlanner.winningPlan. stage

一个表示阶段名称的字符串。

每个阶段都包含特定于阶段的信息。 例如, IXSCAN阶段将包括索引边界以及特定于索引扫描的其他数据。 如果阶段具有子阶段或多个子阶段, 则阶段将具有inputStage或inputStages。 

explain.queryPlanner.winningPlan. inputStage

描述子阶段的文档,它为其父级提供文档或索引键。 如果父级只有一个子级, 则该字段存在。

explain.queryPlanner.winningPlan. inputStages

描述子阶段的一系列文档。 子阶段为父阶段提供文档或索引键。 如果父级具有多个子节点, 则该字段存在。 例如, $or表达式 或 索引交集 的阶段消耗来自多个源的输入。  

explain.queryPlanner. rejectedPlans

查询优化器考虑和拒绝的候选计划数组。 如果没有其他候选计划,则该数组可以为空。

b.executionStats模式

MongoDB运行查询优化器以选择获胜计划,执行获胜计划以完成,并返回描述获胜计划执行的统计信息。对于写入操作, db.collection.explain()返回有关将执行的更新或删除操作的信息,但不会将修改应用于数据库。

db.collection.explain()返回已计算方法的queryPlanner和executionStats信息。但是,executionStats不为被拒绝的计划提供查询执行信息。

对于未加密的集合, explain返回以下executionStats信息:

"executionStats" : {
   "executionSuccess" : <boolean>,
   "nReturned" : <int>,
   "executionTimeMillis" : <int>,
   "totalKeysExamined" : <int>,
   "totalDocsExamined" : <int>,
   "executionStages" : {
      "stage" : <STAGE1>
      "nReturned" : <int>,
      "executionTimeMillisEstimate" : <int>,
      "works" : <int>,
      "advanced" : <int>,
      "needTime" : <int>,
      "needYield" : <int>,
      "saveState" : <int>,
      "restoreState" : <int>,
      "isEOF" : <boolean>,
      ...
      "inputStage" : {
         "stage" : <STAGE2>,
         "nReturned" : <int>,
         "executionTimeMillisEstimate" : <int>,
         ...
         "inputStage" : {
            ...
         }
      }
   },
   "allPlansExecution" : [
      {
         "nReturned" : <int>,
         "executionTimeMillisEstimate" : <int>,
         "totalKeysExamined" : <int>,
         "totalDocsExamined" :<int>,
         "executionStages" : {
            "stage" : <STAGEA>,
            "nReturned" : <int>,
            "executionTimeMillisEstimate" : <int>,
            ...
            "inputStage" : {
               "stage" : <STAGEB>,
               ...
               "inputStage" : {
                 ...
               }
            }
         }
      },
      ...
   ]
}

explain. executionStats

包含描述获胜计划的已完成查询执行的统计信息。 对于写入操作,已完成的查询执行是指将要执行的修改,但不会将修改应用于数据库。

explain.executionStats. nReturned

与查询条件匹配的文档数。 nReturned对应于早期版本的MongoDB中cursor.explain()返回的n字段。

explain.executionStats. executionTimeMillis

查询计划选择和查询执行所需的总时间(以毫秒为单位)。 executionTimeMillis对应于早期版本的MongoDB中cursor.explain()返回的millis字段。

explain.executionStats. totalKeysExamined

扫描的索引条目数。 totalKeysExamined对应于早期版本的MongoDB中cursor.explain()返回的totalKeysExamined字段。

explain.executionStats. totalDocsExamined

查询执行期间检查的文档数。 检查文档的常见查询执行阶段是COLLSCAN和FETCH 。

注意:totalDocsExamined是指检查的文档总数,而不是返回的文档数。 例如,舞台可以检查文档以应用过滤器。 如果文档被过滤掉,那么它已经过检查,

但不会作为查询结果集的一部分返回。 如果在查询执行期间多次检查文档,则totalDocsExamined每次检查进行计数。 也就是说, totalDocsExamined

不是所检查的唯一文档总数的计数。 

explain.executionStats. executionStages

将获胜计划的完成执行细节作为阶段树; 即一个阶段可以有一个inputStage或多个inputStages 。

每个阶段都包含特定于阶段的执行信息。

explain.executionStats.executionStages. works 

指定查询执行阶段执行的“工作单元”的数量。 查询执行将其工作分为小单元。 “工作单位”可能包括检查单个索引键,从集合中提取单个文档,将投影应用于单个文档或执行内部簿记。

explain.executionStats.executionStages. advanced 

此阶段返回或提前的中间结果数到其父阶段。

explain.executionStats.executionStages. needTime

未将中间结果推进到其父级的工作循环数(请参阅explain.executionStats.executionStages.advanced )。 例如,索引扫描阶段可以花费一个工作周期来寻找索引中的新位置而 不是返回索引关键字; 这个工作周期将计入explain.executionStats.executionStages.needTime而不是explain.executionStats.executionStages.advanced 。

explain.executionStats.executionStages. needYield

存储层请求查询阶段暂停处理并产生锁定的次数。

explain.executionStats.executionStages. saveState

查询阶段暂停处理并保存其当前执行状态的次数,例如准备产生锁定。

explain.executionStats.executionStages. restoreState

查询阶段恢复已保存的执行状态的次数,例如在恢复先前已生成的锁之后。

explain.executionStats.executionStages. isEOF

指定执行阶段是否已到达流的结尾:如果为true或1 ,则执行阶段已到达流末尾。

如果为false或0 ,则该阶段可能仍会返回结果。例如,考虑一个带有限制的查询,其执行阶段包含一个LIMIT阶段,其输入阶段为IXSCAN用于查询。如果查询返回超过指定的限制, LIMIT阶段将报告isEOF: 1 ,但其基础IXSCAN阶段将报告isEOF: 0 。

explain.executionStats.executionStages.inputStage. keysExamined

对于扫描索引的查询执行阶段(例如IXSCAN), keysExamined是在索引扫描过程中检查的入站和越界键的总数。 如果索引扫描由单个连续范围的键组成,则只需要检查入站键。

如果索引边界由若干键范围组成,则索引扫描执行过程可以检查越界键,以便从一个范围的末尾跳到下一个范围的开头。  

请考虑以下示例,其中有一个字段x的索引,该集合包含100个x值为1到100的文档:

db.keys.find( { x : { $in : [ 3, 4, 50, 74, 75, 90 ] } } ).explain( "executionStats" ) 

该查询将扫描键3和4 。 然后它将扫描键5 ,检测它是否超出界限,并跳到下一个键50 。继续该过程,查询扫描键3,4,5,50,51,74,75,76,90和91.

键5,51,76和91是仍在检查的越界键。 keysExamined值为10。          

explain.executionStats.executionStages.inputStage. docsExamined

指定在查询执行阶段扫描的文档数。(出现在COLLSCAN阶段,以及从集合中检索文档的阶段(例如FETCH ))

explain.executionStats.executionStages.inputStage. seeks  

版本3.4中的新功能:仅适用于索引扫描( IXSCAN )阶段。我们必须寻找索引光标到新位置才能完成索引扫描的次数。

explain.executionStats. allPlansExecution

包含在计划选择阶段为获胜和被拒绝的计划捕获的部分执行信息。 仅当explain在allPlansExecution详细模式下运行时,该字段才会出现。

执行计划就先看到这里吧。

标签:Index,Use,executionStats,MongoDB,explain,查询,索引,文档,阶段
From: https://blog.51cto.com/u_13753753/6192493

相关文章

  • mongoDB 4.2:赋能未来数据应用的智慧之选
    mongoDB是在2019年发布,具体特性如下图:1.FullTextSearchMongoDB4.2之前,全文搜索(FullTextSearch)的能力是靠TextIndex来支持的,在MongoDB-4.2里,MongoDB直接与Lucene等引擎整合,在Atlas服务里提供全文建索的能力。2.MongoDBFTS原理1.用户可以在Atlas上,对集合开启全......
  • mongoDB 3.0 安全权限访问
    mongoDB3.0访问控制改了很多,需要你老老实实的去看文档去验证,谷歌百度出来的多半就是错误的。还需要注意这个参数authenticationMechanisms。为了兼用2.6版本,我直接指定下面的参数:setParameter:authenticationMechanisms:MONGODB-CR下面看看如何创建访问控制权限不使用—aut......
  • mongodb基础教程
    知识点理解MongoDB的业务场景,熟悉MongoDB的简介,特点和体系结构,数据类型等.能够通过docker-compose创建并启动mongodb和mongo-express掌握MongoDB基本常用命令实现数据的CRUD掌握MongoDB的索引类型,索引管理,执行计划业务场景传统的关系型数据库(比如My......
  • Linux useradd 命令
    Linuxuseradd命令快速使用常用命令说明备注useradd-dtest添加用户并在home下创建默认目录,和adduser不同在于需要通过passwd设置密码,本身没有密码默认无密码账号保存在/etc/passwd简介Linuxuseradd命令用于建立用户帐号。useradd可用来建立用户......
  • How to use command line find all users on Linux All In One
    HowtousecommandlinefindallusersonLinuxAllInOneLinux系统中一切皆文件,就像js中一切皆对象一样/etc/passwd#password$cat/etc/passwdRaspberryPipi@raspberrypi:~$cat/etc/passwd|greppipi:x:1000:1000:,,,:/home/pi:/bin/bashpi@raspbe......
  • SpringBoot 整合 MongoDB
    SpringBoot整合MongoDB好久没搞SpringBoot相关的东西勒,但最近看的代码涉及到了这部分,虽然之前没做过也能看懂,但还是从基础开始搞起比较好。准备工作SpringBoot项目创建这个本来都不用说的,SpringBoot创建项目还能不会啊,但因为某些限制,现在用不了专业版IDEA,只能用社区版,......
  • Springboot集成MongoDB存储文件、读取文件
    一、前言和开发环境及配置可以转载,但请注明出处。  之前自己写的SpringBoot整合MongoDB的聚合查询操作,感兴趣的可以点击查阅。https://www.cnblogs.com/zaoyu/p/springboot-mongodb.html 使用mongodb存储文件并实现读取,通过springboot集成mongodb操作。 可以有两种实现......
  • mongodb 获取集合所有记录中曾出现过的字段
    switchtothedbyou'reusingandtype:mr=db.runCommand({"mapreduce":"myCollectionName","map":function(){for(varkeyinthis){emit(key,null);}},"reduce":function(key,stuff){ret......
  • 【Python】pandas 将某列相同值作为index, 整合数据
    pd.pivot_table#dfvalueUpdateTimefactorNamevalue02023-03-2808:00:18.532805风向147.6912023-03-2808:00:18.532805气压101.7122023-03-2808:00:18.532805风速0.2832023-03-2808:00:18.5328......
  • Access denied for user 'root'@'x.x.x.x' (using password: YES)请求的ip跟报错显示
      这里请求的实际上报这一条错误是说明已经请求到了目标服务器的,mysql中以‘root’@‘x.x.x.x’这种格式表示的ip其实是我们当前的ip而非目标ip,这里报错是因为我密码输错了,所以报了错......