Explain Results
在本页面
要返回有关查询计划的信息和查询计划的执行统计信息,MongoDB 提供:
-
cursor.explain()方法,以及
-
explain命令。
explain
结果将查询计划呈现为阶段树。
"winningPlan" : {
"stage" : <STAGE1>,
...
"inputStage" : {
"stage" : <STAGE2>,
...
"inputStage" : {
"stage" : <STAGE3>,
...
}
}
},
每个阶段将其结果(即文档或索引键)传递给父节点。叶节点访问集合或索引。内部节点操纵由子节点产生的文档或索引键。根节点是 MongoDB 从中得出结果集的最后阶段。
阶段描述了操作;例如
-
COLLSCAN
用于集合扫描 -
IXSCAN
用于扫描索引键 -
FETCH
用于检索文档 -
SHARD_MERGE
用于合并分片的结果 -
SHARDING_FILTER
用于从分片中筛选出孤立文档
Explain Output
以下各节列出了explain
操作返回的一些关键字段。
Note
-
字段列表并不意味着要详尽无遗,而是要突出显示早期解释版本中的一些关键字段更改。
-
输出格式在各个发行版之间可能有所更改。
queryPlanner
queryPlanner信息详细说明了query optimizer选择的计划。
For unsharded collections, explain
returns the following queryPlanner
information:
"queryPlanner" : {
"plannerVersion" : <int>,
"namespace" : <string>,
"indexFilterSet" : <boolean>,
"parsedQuery" : {
...
},
"winningPlan" : {
"stage" : <STAGE1>,
...
"inputStage" : {
"stage" : <STAGE2>,
...
"inputStage" : {
...
}
}
},
"rejectedPlans" : [
<candidate plan 1>,
...
]
}
For sharded collections, explain
includes the core query planner and server information for each accessed shard in the shards
field:
"queryPlanner" : {
"mongosPlannerVersion" : <int>,
"winningPlan" : {
"stage" : <STAGE1>,
"shards" : [
{
"shardName" : <string>,
"connectionString" : <string>,
"serverInfo" : {
"host" : <string>,
"port" : <int>,
"version" : <string>,
"gitVersion" : <string>
},
"plannerVersion" : <int>,
"namespace" : <string>,
...
"winningPlan" : {
"stage" : <STAGE2>,
"inputStage" : {
"stage" : <STAGE3>
...,
}
},
"rejectedPlans" : [
<candidate plan 1>,
...
]
},
...
]
}
}
-
explain.
queryPlanner
- 包含有关query optimizer选择查询计划的信息。
-
explain.queryPlanner.
namespace
- 一个字符串,用于指定要对其运行查询的名称空间(即
<database>.<collection>
)。
- 一个字符串,用于指定要对其运行查询的名称空间(即
-
explain.queryPlanner.
indexFilterSet
- 一个布尔值,指定 MongoDB 是否对query shape应用index filter。
-
explain.queryPlanner.
winningPlan
- 详细说明query optimizer选择的计划的文档。 MongoDB 以阶段树的形式展示了该计划。也就是说,一个阶段可以具有inputStage;如果该阶段具有多个子阶段,则可以具有inputStages。
-
explain.queryPlanner.winningPlan.
stage
-表示舞台名称的字符串。
每个阶段都包含特定于该阶段的信息。例如,一个IXSCAN
阶段将包括索引范围以及特定于索引扫描的其他数据。如果一个阶段具有一个子阶段或多个子阶段,那么该阶段将具有 inputStage 或 inputStages。
-
explain.queryPlanner.winningPlan.
inputStage
-描述子阶段的文档,该文档向其父级提供文档或索引键。 如果父阶段只有一个孩子,则该字段存在。 -
explain.queryPlanner.winningPlan.
inputStages
-一系列描述子阶段的文档。子阶段将文档或索引键提供给父阶段。如果父级具有多个子节点,则该字段存在。例如,$or expressions或index intersection的阶段消耗来自多个来源的 Importing。 -
explain.queryPlanner.
rejectedPlans
- 查询优化器考虑和拒绝的候选计划数组。如果没有其他候选计划,则该数组可以为空。
executionStats
返回的executionStats信息详细说明了获胜计划的执行情况。为了在结果中包含executionStats
,您必须运行以下任一命令中的解释:
-
allPlansExecution详细模式。使用
allPlansExecution
模式包括在plan selection期间捕获的部分执行数据。
For unsharded collections, explain
returns the following executionStats
information:
"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" : {
...
}
}
}
},
...
]
}
For sharded collections, explain
includes the execution statistics for each accessed shard.
"executionStats" : {
"nReturned" : <int>,
"executionTimeMillis" : <int>,
"totalKeysExamined" : <int>,
"totalDocsExamined" : <int>,
"executionStages" : {
"stage" : <STAGE1>
"nReturned" : <int>,
"executionTimeMillis" : <int>,
"totalKeysExamined" : <int>,
"totalDocsExamined" : <int>,
"totalChildMillis" : <NumberLong>,
"shards" : [
{
"shardName" : <string>,
"executionSuccess" : <boolean>,
"executionStages" : {
"stage" : <STAGE2>,
"nReturned" : <int>,
"executionTimeMillisEstimate" : <int>,
...
"chunkSkips" : <int>,
"inputStage" : {
"stage" : <STAGE3>,
...
"inputStage" : {
...
}
}
}
},
...
]
}
"allPlansExecution" : [
{
"shardName" : <string>,
"allPlans" : [
{
"nReturned" : <int>,
"executionTimeMillisEstimate" : <int>,
"totalKeysExamined" : <int>,
"totalDocsExamined" :<int>,
"executionStages" : {
"stage" : <STAGEA>,
"nReturned" : <int>,
"executionTimeMillisEstimate" : <int>,
...
"inputStage" : {
"stage" : <STAGEB>,
...
"inputStage" : {
...
}
}
}
},
...
]
},
{
"shardName" : <string>,
"allPlans" : [
...
]
},
...
]
}
-
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()
返回的nscanned
字段。
- 扫描的索引条目数。 totalKeysExamined对应于 MongoDB 早期版本中
-
explain.executionStats.
totalDocsExamined
- 查询执行期间检查的文档数。检查文档的常见查询执行阶段是
COLLSCAN
和FETCH
。
- 查询执行期间检查的文档数。检查文档的常见查询执行阶段是
Note
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
阶段和一个 ImportingIXSCAN
的阶段组成。如果查询返回的值大于指定的限制,则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
。
continue 此过程,查询将扫描键 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
详细级别模式运行时,此字段才存在。
- 包含在计划选择阶段期间为获胜和拒绝计划捕获的部分执行信息。仅当
serverInfo
For unsharded collections, explain
returns the following serverInfo
information for the MongoDB instance:
"serverInfo" : {
"host" : <string>,
"port" : <int>,
"version" : <string>,
"gitVersion" : <string>
}
For sharded collections, explain
returns the serverInfo
for each accessed shard, and a top-level serverInfo
object for the mongos.
"queryPlanner" : {
...
"winningPlan" : {
"stage" : <STAGE1>,
"shards" : [
{
"shardName" : <string>,
"connectionString" : <string>,
"serverInfo" : {
"host" : <string>,
"port" : <int>,
"version" : <string>,
"gitVersion" : <string>
},
...
}
...
]
}
},
"serverInfo" : { // serverInfo for mongos (new in 3.6.16)
"host" : <string>,
"port" : <int>,
"version" : <string>,
"gitVersion" : <string>
}
Format Change
从 MongoDB 3.0 开始,explain
结果的格式和字段与以前的版本已更改。以下列出了一些主要区别。
集合扫描与索引使用
如果查询计划者选择了集合扫描,则说明结果将包括COLLSCAN
阶段。
如果查询计划者选择了索引,则说明结果包括IXSCAN
阶段。该阶段包括诸如索引键样式,遍历方向和索引边界之类的信息。
在以前的 MongoDB 版本中,cursor.explain()
返回了cursor
字段,其值为:
-
BasicCursor
用于集合扫描,以及 -
BtreeCursor <index name> [<direction>]
用于索引扫描。
有关收集扫描和索引扫描的执行统计信息的更多信息,请参见分析查询性能。
Covered Queries
当索引涵盖查询时,MongoDB 既可以匹配查询条件,也可以仅使用索引键返回结果;即 MongoDB 无需检查集合中的文档即可返回结果。
当索引覆盖查询时,解释结果将具有IXSCAN
阶段,该阶段不是FETCH
阶段的后代,而在executionStats中,totalDocsExamined
是0
。
在早期版本的 MongoDB 中,cursor.explain()
返回indexOnly
字段以指示索引是否覆盖查询。
Index Intersection
对于索引交叉口计划,结果将包括AND_SORTED
阶段或AND_HASH
阶段以及带有详细说明索引的inputStages数组;例如。:
{
"stage" : "AND_SORTED",
"inputStages" : [
{
"stage" : "IXSCAN",
...
},
{
"stage" : "IXSCAN",
...
}
]
}
在以前的 MongoDB 版本中,cursor.explain()
返回了cursor
字段,其中Complex Plan
的值用于索引交集。
$or Expression
如果 MongoDB 对$or表达式使用索引,则结果将包括OR
阶段和inputStages
数组,该数组详细描述了索引;例如。:
{
"stage" : "OR",
"inputStages" : [
{
"stage" : "IXSCAN",
...
},
{
"stage" : "IXSCAN",
...
},
...
]
}
在以前的 MongoDB 版本中,cursor.explain()
返回了详细说明索引的clauses
数组。
Sort Stage
如果 MongoDB 可以使用索引扫描来获取请求的排序 Sequences,则结果将不包括SORT
阶段。否则,如果 MongoDB 无法使用索引进行排序,则explain
结果将包含SORT
阶段。
在 MongoDB 3.0 之前,cursor.explain()
返回scanAndOrder
字段以指定 MongoDB 是否可以使用索引 Sequences 返回排序的结果。