提高查询效率,掌握MongoDB 4.2索引策略中的Measure Index Use技术
  nQkVcpdWfLDr 2023年11月02日 40 0

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详细模式下运行时,该字段才会出现。

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

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  lG7RE7vNF4mc   2023年11月13日   30   0   0 3d权重字段
  wpWn7yzs0oKF   2023年11月13日   37   0   0 数据库字段SQL
  dIZ4mPo2q5Ch   2023年11月02日   64   0   0 字段分隔符CentOS
  nQkVcpdWfLDr   2023年11月13日   34   0   0 数据2d字段
nQkVcpdWfLDr