为了返回有关查询计划和查询计划执行统计信息,MongoDB 提供了以下方法:
要了解重要的解释结果字段以及如何加以解释,请参阅解释“解释计划结果”。
重要
explain 忽略计划缓存。相反,系统会生成一组候选计划,并在不咨询计划缓存的情况下选择获胜者。此外,explain 会阻止 MongoDB 查询规划器缓存获胜计划。
注意
此页面仅显示最重要的输出字段,未记录供内部使用的字段。输出中列出的字段可能会发生变化。
解释输出结构
explain 结果将查询计划显示为阶段树。输出结构可能因操作使用的查询引擎而异。操作可以使用经典查询引擎或基于插槽的执行查询引擎。
此结构适用于 db.collection.find() 和使用相同查询系统的命令,例如count、distinct、update 和 findAndModify。聚合操作返回一个不同的结构,其中具有顶级 stages大量。要学习;了解如何读取聚合解释输出,请参阅聚合解释输出。
参阅以下示例,了解这两个执行引擎的输出结构有何不同:
winningPlan: { stage: <STAGE1>, ... inputStage: { stage: <STAGE2>, ... inputStage: { stage: <STAGE3>, ... } } },
winningPlan: { queryPlan: { stage: <STAGE1>, ... inputStage: { stage: <STAGE2>, ... inputStage: { stage: <STAGE3>, ... } } } slotBasedPlan: { ... } },
每个阶段都将其生成的文档或索引键传递到父节点。叶节点访问集合或索引。内部节点使用由子节点产生的文档或索引键。根节点指示 MongoDB 最终派生出结果集的阶段。
阶段是对操作的描述。例如:
COLLSCAN用于集合扫描IXSCAN用于扫描索引键FETCH用于检索文档GROUP用于对文档进行分组SHARD_MERGE用来合并来自分片的结果SHARDING_FILTER用于从分片中筛掉孤儿文档TS_MODIFY用于修改时间序列集合BATCHED_DELETE用于在内部批处理的多个文档删除(从 MongoDB 6.1 开始)EOF用于当阶段处于流结束时EXPRESS为一组有限的查询提供阶段,这些查询可以绕过常规查询计划,使用优化的索引扫描计划(版本 8.0 中的新功能。)EXPRESS阶段可以是以下之一:EXPRESS_CLUSTERED_IXSCANEXPRESS_DELETEEXPRESS_IXSCANEXPRESS_UPDATE
解释 MongoDB 5.1 和更高版本的输出
本部分显示 MongoDB 5.1 及更高版本的 explain 输出。要查看旧版本 MongoDB 的解释输出,请参阅该版本的文档。
queryPlanner
explain.queryPlanner information details the plan selected by the query optimizer.
注意
从 MongoDB 8.3 开始,多计划同 CBR 备份是符合条件的查询的默认计划选择机制。在短暂的试用期间,多计划器会尝试找到能在这个短暂时间内返回结果集的计划。如果尝试失败,MongoDB 会应用一系列规则来确定多计划器是否应继续,或者 CBR 是否应评估计划中的每个节点以确定最优计划。
有关更多信息,请参阅 查询计划选项。
这些示例可能结合了经典执行引擎和基于槽位的执行引擎的输出结构。它们并不具有代表性。您的输出可能与之有巨大差异。
对于未分片的集合,explain 将返回以下 queryPlanner 信息:
queryPlanner: { namespace: <string>, indexFilterSet: <boolean>, parsedQuery: { ... }, planCacheShapeHash: <hexadecimal string>, planCacheKey: <hexadecimal string>, maxIndexedOrSolutionsReached: <boolean>, maxIndexedAndSolutionsReached: <boolean>, maxScansToExplodeReached: <boolean>, winningPlan: { stage: <STAGE1>, type: <string>, inputStage: { stage: <string>, ... } }, rejectedPlans: [ <candidate plan1>, ] }
从MongoDB 8.0 开始,现有的 queryHash字段将复制到名为 planCacheShapeHash 的新字段中。 如果您使用的是早期MongoDB版本,则只能看到 queryHash字段。 未来的MongoDB版本将删除已弃用的 queryHash字段,您需要改用 planCacheShapeHash字段。
对于分片集合,explain 包括核心查询规划器和 shards 字段中每个被访问分片的服务器信息:
{ queryPlanner: { mongosPlannerVersion: <int> winningPlan: { stage: <STAGE1>, type: <string>, shards: [ { shardName: <string>, connectionString: <string>, serverInfo: { ... }, namespace: <string>, indexFilterSet: <boolean>, parsedQuery: { ... }, querySettings: { ... }, planCacheShapeHash: <hexadecimal string>, planCacheKey: <hexadecimal string>, maxIndexedOrSolutionsReached: <boolean>, maxIndexedAndSolutionsReached: <boolean>, maxScansToExplodeReached: <boolean>, winningPlan: { stage: <STAGE1>, type: <string>, inputStage: { stage: <string>, ... } }, rejectedPlans: [ <candidate plan1>, ] } ] } } }
如果查询优化器使用基于成本的排名器,则输出包含几个附加字段。
{ queryPlanner: { mongosPlannerVersion: <int> winningPlan: { isCached: <boolean>, stage: <STAGE1>, costEstimate: <float>, cardinalityEstimate: <float>, estimatesMetadata: { ceSource: '<string>' }, inputStage: { stage: <STAGE1>, costEstimate: <float>, cardinalityEstimate: <float>, filterNumKeysEstimate: <float>, numKeysEstimate: <float>, estimatesMetadata: { ceSource: '<string>'} , ... } } } }
从MongoDB 8.0 开始,现有的 queryHash字段将复制到名为 planCacheShapeHash 的新字段中。 如果您使用的是早期MongoDB版本,则只能看到 queryHash字段。 未来的MongoDB版本将删除已弃用的 queryHash字段,您需要改用 planCacheShapeHash字段。
explain.queryPlanner包含查询优化器所选查询计划的相关信息。
explain.queryPlanner.namespace一个字符串,使用数据库的名称和查询访问的集合指定该命名空间。该命名空间的格式为
<database>.<collection>。
explain.queryPlanner.querySettings如果设置了查询设置,则
querySettings包含有关应用于查询结构的查询设置的详细信息。要添加查询设置并浏览示例(其中包括
explain()输出和querySettings),请参阅setQuerySettings。8.0版本新增。
explain.queryPlanner.planCacheShapeHash从MongoDB 8.0 开始,现有的
queryHash字段将复制到名为planCacheShapeHash的新字段中。 如果您使用的是早期MongoDB版本,则只能看到queryHash字段。 未来的MongoDB版本将删除已弃用的queryHash字段,您需要改用planCacheShapeHash字段。一个十六进制字符串,表示计划缓存查询结构的哈希值,并且仅依赖于计划缓存查询结构。
planCacheShapeHash可以帮助识别具有相同计划缓存查询结构的慢查询(包括写入操作的查询筛选条件)。注意
与任何哈希函数一样,两个不同的计划缓存查询结构可能会产生相同的哈希值。但是,不同计划缓存查询结构之间不太可能发生哈希冲突。
有关
planCacheShapeHash和planCacheKey的更多信息,请参阅 planCacheShapeHash 和 planCacheKey。
explain.queryPlanner.planCacheKey与此查询关联的计划缓存条目的键的哈希值。
Unlike the
explain.queryPlanner.planCacheShapeHash, theexplain.queryPlanner.planCacheKeyis a function of both the plan cache query shape and the currently available indexes for that shape. Specifically, if indexes that can support the query shape are added or dropped, theplanCacheKeyvalue may change but theplanCacheShapeHashvalue wouldn't change.有关
planCacheShapeHash和planCacheKey的更多信息,请参阅 planCacheShapeHash 和 planCacheKey。
explain.queryPlanner.optimizationTimeMillis查询规划器在查询优化上花费的时间(以毫秒为单位)。此结果不包括优化内部
$lookup查询所花费的时间。
explain.queryPlanner.optimizedPipeline一个布尔值,表明整个聚合管道操作已被优化掉,改用查询计划执行阶段树来实现。
例如,以下聚合操作可以通过查询计划执行树来完成,而不使用聚合管道。
db.example.aggregate([ { $match: { someFlag: true } } ] ) 仅当值为
true时,该字段才存在,并且仅适用于解释聚合管道操作。为true时,由于管道已被优化掉,所以输出中不会出现聚合阶段信息。
explain.queryPlanner.winningPlan详细说明查询优化器所选计划的文档。
explain.queryPlanner.winningPlan.stage一个表示阶段名称的字符串。
每个阶段都包含针对该阶段的信息。例如,
IXSCAN阶段包括索引边界和索引扫描的其他特定数据。如果一个阶段有一个或多个子阶段,则该阶段将有一个inputStage或inputStages。如果该操作使用经典查询执行引擎,则会显示此字段。
explain.queryPlanner.winningPlan.type如果将
stage设立为"EOF",则type是一个字符串,表示 EOF 阶段的原因:"nonExistentNamespace":表示查询命名空间不存在。"predicateEvalsToFalse":表示表达式简化确定该查询不会匹配任何文档。
explain.queryPlanner.winningPlan.inputStagesAn array of documents describing the child stages. Child stages provide the documents or index keys to the parent stage. The field is present if the parent stage has multiple child nodes. For example, stages for $or expressions might consume input from multiple sources.
如果该操作使用经典查询执行引擎,则会显示此字段。
explain.queryPlanner.winningPlan.isCached一个布尔值,用于指示赢得计划是否在计划缓存中。
对于获胜计划和被拒绝计划之间最多一个计划,此字段为
true。 如果查询没有缓存计划,则对于获胜计划和被拒绝的计划,该字段为false。
explain.queryPlanner.winningPlan.costEstimate代表每个阶段用于执行基于成本排名器的估计抽象成本单位的浮点。基于成本的排名器选择具有最低顶级
costEstimate的计划。8.3.3版本新增。
explain.queryPlanner.winningPlan.numKeysEstimate表示查询计划程序预测计划处理的索引密钥的估计数量的浮点数。
numKeysEstimate和costEstimate之间的显著差异可能表明winningPlan存在问题。8.3.3版本新增。
explain.queryPlanner.winningPlan.estimatesMetadata.ceSource此阶段使用的关联基数估计方法 (CE)。可能的浮点值包括:
sampling: MongoDB 会在基础集合的示例上计算估计。heuristics: 使用一组规则来确定选择性。仅在采样失败时使用。mixed:该估计是某些计算的结果,该计算混合了不同类型的估计。metadata: 估计来自数据库元数据,例如集合关联基数。code: C++ 直接计算估计值,例如常量或表达式。
8.3.3版本新增。
explain.queryPlanner.winningPlan.queryPlan一份详细说明查询优化器所选计划的文档。MongoDB 将计划表示为阶段树。
如果查询使用基于槽位的执行查询引擎,则此文档出现。
5.1版本新增。
explain.queryPlanner.winningPlan.queryPlan.stage一个表示阶段名称的字符串。
每个阶段都包含针对该阶段的信息。例如,
IXSCAN阶段包括索引边界和索引扫描的其他特定数据。
explain.queryPlanner.winningPlan.queryPlan.type如果将
stage设立为"EOF",则type是一个字符串,表示 EOF 阶段的原因:"nonExistentNamespace":表示查询命名空间不存在。"predicateEvalsToFalse":表示表达式简化确定该查询不会匹配任何文档。
explain.queryPlanner.winningPlan.queryPlan.planNodeId标识执行计划中每个阶段的唯一整型字段。字段包含在整个
explain结果的所有阶段中。5.1版本新增。
explain.queryPlanner.winningPlan.slotBasedPlan.stages包含基于插槽的查询执行计划中每个阶段的信息的字符串,包括执行顺序、操作和插槽分配。供 MongoDB 内部使用。
从 MongoDB 8.0开始,如果查询使用块处理,则
block_to_row和ts_bucket_to_cellblock会出现在stages输出中。在版本8.0中进行了更改。
explain.queryPlanner.rejectedPlans查询优化器考虑和拒绝的候选计划数组。如果没有其他候选计划,则数组可能为空。
被拒绝的计划具有与
explain.queryPlanner.winningPlan相同的字段。从 MongoDB 8.0 开始,被拒绝的查询计划只包含查询的
find部分。在以前的版本中,被拒绝的计划可以包含聚合阶段,例如$group。查询规划器不使用这些聚合阶段来选择获胜计划,因此rejectedPlans字段只包含查询中用于选择获胜计划的部分。
executionStats
The returned explain.executionStats information details the execution of the winning plan. To include executionStats in the results, you must run the explain in either:
allPlansExecution 冗余模式。使用
allPlansExecution模式以包含计划选择过程中捕获的部分执行数据。
这些示例可能结合了经典执行引擎和基于槽位的执行引擎的输出结构。它们并不具有代表性。您的输出可能与之有巨大差异。
对于未分片的集合,explain 将返回以下 executionStats 信息:
executionStats: { executionSuccess: <boolean>, nReturned: <int>, executionTimeMillis: <int>, totalKeysExamined: <int>, totalDocsExamined: <int>, executionStages: { stage: <STAGE1> nReturned: <int>, executionTimeMillisEstimate: <int>, opens: <int>, // Starting in MongoDB 5.1 closes: <int>, // Starting in MongoDB 5.1 works: <int>, advanced: <int>, needTime: <int>, needYield: <int>, saveState: <int>, restoreState: <int>, isEOF: <boolean>, ... inputStage: { stage: <STAGE2>, nReturned: <int>, ... numReads: <int>, // Starting in MongoDB 5.1 ... executionTimeMillisEstimate: <int>, ... spills: <long long>, spilledBytes: <long long>, spilledRecords: <long long>, spilledDataStorageSize: <long long>, peakTrackedMemBytes: <long>, // Starting in 8.3 ... inputStage: { ... } } }, allPlansExecution: [ { nReturned: <int>, executionTimeMillisEstimate: <int>, totalKeysExamined: <int>, totalDocsExamined: <int>, score: <double>, executionStages: { stage: <STAGEA>, nReturned: <int>, executionTimeMillisEstimate: <int>, ... inputStage: { stage: <STAGEB>, ... inputStage: { ... } } } }, ... ] operationMetrics: { cpuNanos: <int>, cursorSeeks: <int>, docBytesRead: <int>, docBytesWritten: <int>, docUnitsRead: <int>, docUnitsReturned: <int>, docUnitsWritten: <int>, idxEntryBytesRead: <int>, idxEntryBytesWritten: <int>, idxEntryUnitsRead: <int>, idxEntryUnitsWritten: <int>, totalUnitsWritten: <int>, keysSorted: <int>, sorterSpills: <int> } }, ... peakTrackedMemBytes: <long>, // Starting in 8.3 ...
对于分片集合,explain 包括每个访问的分片的执行统计信息。
executionStats: { nReturned: <int>, executionTimeMillis: <int>, totalKeysExamined: <int>, totalDocsExamined: <int>, executionStages: { stage: <STAGE1> nReturned: <int>, executionTimeMillis: <int>, opens: <int>, // Starting in MongoDB 5.1 closes: <int>, // Starting in MongoDB 5.1 totalKeysExamined: <int>, totalDocsExamined: <int>, totalChildMillis: <NumberLong>, shards: [ { shardName: <string>, executionSuccess: <boolean>, executionStages: { stage: <STAGE2>, nReturned: <int>, executionTimeMillisEstimate: <int>, ... chunkSkips: <int>, inputStage: { stage: <STAGE3>, ... numReads: <int>, // Starting in MongoDB 5.1 ... spills: <long long>, spilledBytes: <long long>, spilledRecords: <long long>, spilledDataStorageSize: <long long>, peakTrackedMemBytes: <long>, // Starting in 8.3 ... inputStage: { ... } } } }, ... ] } allPlansExecution: [ { shardName: <string>, allPlans: [ { nReturned: <int>, executionTimeMillisEstimate: <int>, peakTrackedMemBytes: <long>, // Starting in 8.3 totalKeysExamined: <int>, totalDocsExamined:<int>, executionStages: { stage: <STAGEA>, nReturned: <int>, executionTimeMillisEstimate: <int>, ... inputStage: { stage: <STAGEB>, ... inputStage: { ... } } } }, ... ] }, { shardName: <string>, allPlans: [ ... ] }, ... ], peakTrackedMemBytes: <long>, // Starting in 8.3 ... }
explain.executionStats包含描述入选计划的已完成查询执行的统计信息。对于写入操作,已完成的查询执行是指将要执行的修改,但不将这些修改应用到数据库。
explain.executionStats.nReturnedNumber of documents returned by the winning query plan.
nReturnedcorresponds to thenfield returned bycursor.explain()in earlier versions of MongoDB.
explain.executionStats.executionTimeMillis选择查询计划和执行查询所需的总时间(以毫秒为单位)。它包括运行计划选择过程的试用阶段部分所需的时间,但不包括将数据传输回客户端的网络时间。
explain.executionStats.executionTimeMillis报告的时间不一定代表实际查询时间。在稳定状态操作期间(缓存查询计划时),或者将cursor.hint()与cursor.explain()一起使用时,MongoDB 会绕过计划选择过程,从而缩短实际时间,从而导致explain.executionStats.executionTimeMillis值更低。
explain.executionStats.peakTrackedMemBytes8.3版本新增。
当前查询操作使用的跟踪内存的最大字节数。
解释执行统计信息提供了整个查询以及每个阻塞阶段的峰值内存。如果只有一个阻塞阶段,则查询和阶段
peakTrackedMemBytes值相同。
explain.executionStats.totalKeysExaminedNumber of index entries scanned.
explain.executionStats.totalKeysExaminedcorresponds to thenscannedfield returned bycursor.explain()in earlier versions of MongoDB.
explain.executionStats.totalDocsExamined查询执行过程中检查的文档数量。检查文档的常见查询执行阶段是
COLLSCAN和FETCH。注意
explain.executionStats.totalDocsExaminedrefers to the total number of documents examined and not to the number of documents returned. For example, a stage can examine a document in order to apply a filter. If the document is filtered out, then it has been examined but will not be returned as part of the query result set.If a document is examined multiple times during query execution,
explain.executionStats.totalDocsExaminedcounts each examination. That is,explain.executionStats.totalDocsExaminedis not a count of the total number of unique documents examined.
explain.executionStats.executionStages以阶段树的形式详细说明获胜计划的执行情况;即一个阶段可以有一个
inputStage或多个inputStages。从 MongoDB 5.1 开始,一个阶段可以具有以下输入阶段:
thenStageelseStageinnerStageouterStage
每个阶段都包含针对该阶段的执行信息。
explain.executionStats.executionStages.works指定查询执行阶段执行的“工作单元”数量。查询执行将其工作划分为多个小单元。“工作单元”可能包括检查单个索引键、从集合中获取单个文档、将投影应用于单个文档或进行内部簿记。
如果该操作使用经典查询执行引擎,则会显示此字段。
explain.executionStats.executionStages.isEOF指定执行阶段是否已到达流结束:
如果为
true或1,则执行阶段已到达流结束。如果为
false或0,则该阶段可能仍有结果要返回。考虑一个具有限制的查询,其执行阶段由LIMIT个阶段组成,输入阶段为IXSCAN。如果查询返回的结果超过指定的限制,则LIMIT阶段将报告isEOF: 1,但其底层的IXSCAN阶段将报告isEOF: 0。
explain.executionStats.executionStages.inputStage每个
inputStage可以有不同的字段,具体取决于inputStage.stage的值。下表描述了可能的字段以及它们可以出现在哪些阶段。Each
inputStagecan have anotherinputStageas a field. See Explain Output Structure.字段说明适用阶段docsExamined指定在查询执行阶段扫描的文档数量。
COLLSCAN,FETCHkeysExamined对于扫描索引的查询执行阶段,
keysExamined是在索引扫描过程中检查的界内和界外键的总数。如果索引扫描由单个连续范围的键组成,则仅需要检查界内键。如果索引边界由多个键范围组成,则索引扫描执行过程可能会检查界外键,以便从一个范围的末尾跳到下一个范围的开头。IXSCANnumReads在查询执行阶段扫描的文档或检查的索引键的数量。
5.1版本新增。
COLLSCAN,IXSCANseeks为了完成索引扫描而必须让索引游标搜索新位置的次数。
IXSCANusedDisk该阶段是否已写入磁盘。
5.3版本新增。
GROUPspills该阶段溢出到磁盘的次数。
8.2版本新增。
GROUP,SORTspilledBytes写入磁盘的数据总量(以字节为单位)。
8.2版本新增。
GROUP,SORTspilledRecords溢出到磁盘的单条记录总数。
8.2版本新增。
GROUP,SORTspilledDataStorageSize溢出数据使用的总磁盘空间(以字节为单位)。
8.2版本新增。
GROUP,SORTpeakTrackedMemBytes8.3版本新增。
当前查询操作使用的跟踪内存的最大字节数。
从 MongoDB 9.0 开始,
COUNT_SCAN、GEO_NEAR_2D、GEO_NEAR_2DSPHERE和UPDATE阶段也会报告此字段。COUNT_SCAN,GEO_NEAR_2D,GEO_NEAR_2DSPHERE,GROUP,SORT,UPDATE
explain.executionStats.allPlansExecution包含在计划选择阶段为中标和被拒计划捕获的部分执行信息。该字段仅在
explain以allPlansExecution详细模式运行时出现。
explain.executionStats.operationMetrics包含资源消耗统计信息,只要它们不为零。仅当
explain在executionStats详细模式或更高模式下运行并且profileOperationResourceConsumptionMetrics已启用时,该字段才会出现。警告
MongoDB 8.2 删除
profileOperationResourceConsumptionMetrics。因此,依赖于operationMetrics的代码不起作用。
serverInfo
对于未分片集合, explain 返回 MongoDB 实例的以下 serverInfo 信息:
serverInfo: { host: <string>, port: <int>, version: <string>, gitVersion: <string> }
对于分片集合, explain 返回每个所访问分片的 serverInfo,并返回 mongos 的顶级 serverInfo 对象。
queryPlanner: { ... winningPlan: { stage: <STAGE1>, shards: [ { shardName: <string>, connectionString: <string>, serverInfo: { host: <string>, port: <int>, version: <string>, gitVersion: <string> }, ... } ... ] } }, serverInfo: { // serverInfo for mongos host: <string>, port: <int>, version: <string>, gitVersion: <string> } ...
具有 管道阶段的查询的执行计划统计信息$lookup
版本 5.0 中的新增功能。
The explain results can include execution statistics for queries that use a $lookup pipeline stage. To include those execution statistics, you must run the explain operation in one of these execution verbosity modes:
以下字段包含在 $lookup 查询的解释结果中:
'$lookup': { from: <string>, as: <string>, localField: <string>, foreignField: <string> }, totalDocsExamined: <long>, totalKeysExamined: <long>, collectionScans: <long>, indexesUsed: [ <string_1>, <string_2>, ..., <string_n> ], executionTimeMillisEstimate: <long>
要查看 $lookup 部分中字段的说明,请参阅 $lookup 页面。
其他字段为:
搜索查询的执行计划统计信息
8.1版本新增。
The explain results includes execution statistics for queries that use a $search, $searchMeta, or $vectorSearch pipeline stage. To include execution statistics for search queries, run the explain command in one of the following execution verbosity modes:
MongoDB返回仅使用经典引擎的搜索和向量搜索查询的执行统计信息。
有关搜索和向量搜索查询解释结果的更多详细信息,请参阅:
集合扫描(collection scan)
如果查询规划器选择集合扫描,解释结果将包含 COLLSCAN 阶段。
如果查询规划器选择索引,解释结果将包含 IXSCAN 阶段。该阶段包括索引键模式、遍历方向和索引边界等信息。
从 MongoDB 5.3 开始,如果查询规划器为集群化集合选择了集群化索引,且查询包含定义要搜索的索引部分的边界,则解释结果会包含一个 CLUSTERED_IXSCAN 阶段。该阶段包含有关集群化索引键和索引边界的信息。
如果查询规划器为集群化集合选择集群化索引,且查询不包含边界,则查询将执行无边界集合扫描,解释结果包括 COLLSCAN 阶段。
注意
notablescan 参数不允许使用集群索引的无界查询,因为这些查询需要完整的集合扫描。
有关集合扫描的执行统计数据的更多信息,请参阅解释“解释计划结果”。
覆盖查询
当索引涵盖查询时,MongoDB 可以仅使用索引键来匹配查询条件并返回结果。MongoDB 无需检查集合中的文档即可执行查询的任何部分。
当索引覆盖查询时,解释结果中的 IXSCAN 阶段不是 FETCH 阶段的后代。
$or 表达式(expression)
If MongoDB uses indexes for an $or expression, the result will include the OR stage with an explain.queryPlanner.winningPlan.inputStages array that details the indexes; e.g.:
{ stage: 'OR', inputStages: [ { stage: 'IXSCAN', ... }, { stage : 'IXSCAN', ... }, ... ] }
在早期版本的 MongoDB 中,cursor.explain() 返回详细说明索引的 clauses 数组。
聚合解释输出
当您在聚合上运行explain 时,输出包含顶级 stages大量,而不是单个查询计划树。大量中的第一个条目通常是 $cursor,其中包含管道的数据访问部分。 $cursor 条目包含与 find 解释输出返回的相同 queryPlanner 和 executionStats 对象。 $cursor 之后的条目在聚合框架中运行。
阶段被吸收到 $cursor
stages大量通常与管道中的阶段不匹配。在优化过程中, MongoDB会将一些管道工作转移到查询系统可以使用索引更有效地完成该工作。示例, MongoDB可以执行以下优化:
前导
$match、$sort和$limit阶段均会被$cursor吸收。被吸收的$match在查询计划中显示为filter,被吸收的$limit显示为LIMIT阶段。$group和$lookup可以作为GROUP和EQ_LOOKUP阶段推送到查询计划中。要学习;了解更多信息,请参阅$group优化和$lookup优化。如果索引提供了请求的排序顺序,则不会显示单独的
$sort条目。$project和其他阶段也可以推送到查询计划中,具体取决于MongoDB版本和所使用的查询引擎。
此列表并非详尽。 MongoDB吸收或下推哪些阶段可能会因版本而异。有关MongoDB如何在执行前重塑管道的一般信息,请参阅聚合管道优化。
因此,stages大量包含的条目数少于您运行的管道。要查看服务器运行的阶段,请将 stages大量与同一输出中的 command.pipeline字段进行比较。
例子
以下聚合具有三个管道阶段:
db.comments.aggregate( [ { $match: { date: { $gte: ISODate("2015-01-01") } } }, { $group: { _id: "$movie_id", commentCount: { $sum: 1 } } }, { $sort: { commentCount: -1 } } ], { explain: true } )
输出仅包含 stages大量中的两个条目:
{ explainVersion: '2', stages: [ { '$cursor': { queryPlanner: { namespace: 'sample_mflix.comments', parsedQuery: { date: { '$gte': ISODate('2015-01-01T00:00:00.000Z') } }, ... winningPlan: { isCached: false, queryPlan: { stage: 'GROUP', planNodeId: 3, inputStage: { stage: 'COLLSCAN', planNodeId: 1, filter: { date: { '$gte': ISODate('2015-01-01T00:00:00.000Z') } }, direction: 'forward' } }, ... }, rejectedPlans: [] }, ... }, nReturned: Long('697'), executionTimeMillisEstimate: Long('31') }, { '$sort': { sortKey: { commentCount: -1 } }, totalDataSizeSortedBytesEstimate: Long('170765'), usedDisk: false, spills: Long('0'), spilledDataStorageSize: Long('0'), nReturned: Long('697'), executionTimeMillisEstimate: Long('31') } ], ... }
输出显示以下内容:
优化掉的管道
如果查询系统可以运行管道中的每个阶段,则 stages大量不会出现在输出中。相反,输出包含设立为 true 的 explain.queryPlanner.optimizedPipeline字段,并且没有聚合阶段信息。
具有溢出指标的聚合阶段
当 explain 在 executionStats 或 allPlansExecution 详细程度模式下运行时,某些可能会溢出到磁盘的聚合阶段会有额外的输出。这些阶段包括 $sort、$group、$setWindowFields、$bucketAuto、$graphLookup 和 $lookup (使用基于槽的执行引擎时)。从 MongoDB 8.1 开始,这也包括使用 TextOr 执行阶段的 $text 查询。
8.1版本新增。
阶段 | 字段 | 类型 | 说明 |
|---|---|---|---|
| long |
| |
| 布尔 | 该阶段是否已写入磁盘。 | |
| long long | 该阶段溢出到磁盘的次数。 | |
| long long | 压缩前写入磁盘的估计字节数。 | |
| long long | 溢出到磁盘的单条记录总数。 | |
| long long | 溢出数据使用的总磁盘空间(以字节为单位)。 | |
| long long | 在阶段执行期间跟踪的峰值内存使用量(以字节为单位)。 |
具有表达式内存跟踪的聚合阶段
从 MongoDB 9.0 开始,当您在 executionStats 详细程度模式下运行 explain 时,使用经典查询执行引擎的聚合阶段会输出一个 expressionEvaluationPeakMemoryBytes 字段。该字段包含阶段执行期间表达式评估产生的峰值内存使用量(以字节为单位)。
9.0版本新增。
以下阶段报告 expressionEvaluationPeakMemoryBytes:
要了解 MongoDB 如何在聚合过程中限制内存使用,请参阅每个操作的内存限制。
排序阶段
如果MongoDB无法使用一个或多个索引来获取排序顺序,则结果将包含一个指示内存中排序操作的 SORT 阶段。如果解释计划不包含显式 SORT 阶段,则MongoDB使用索引来获取排序顺序。
在聚合解释输出中,内存中排序可以显示为顶级 stages大量中的 $sort 条目,而不是查询计划中的 SORT 阶段。即使查询计划不包含SORT 阶段,管道可以执行内存中排序。要学习;了解更多信息,请参阅聚合解释输出。
查询结构哈希
从 MongoDB 8.0 开始,explain 输出以下字段:
查询参数
9.0版本新增。
从 MongoDB 9.0 开始,explain 输出以下字段:
explain.queryKnobs一份显示每个查询旋钮有效值及其来源的文档。
每个字段的形式为
{ "value": <value>, "source": <string> }。使用setQuerySettings命令设置查询控制时,MongoDB 会将source值设置为"querySettings"。当您使用setParameter设置查询旋钮时,MongoDB 会将source值设置为"setParameter"。通过查询设置设置的查询旋钮始终显示,即使其值等于默认值。但是,
explain输出会省略您未明确设置的查询旋钮。要了解更多信息,请参阅 查询旋钮 (Query Knobs)。