To return information on query plans and execution statistics of the query plans, MongoDB provides the following methods:
To learn about important explain result fields and how to interpret them, see Interpret Explain Plan Results.
Important
explain ignores the plan cache. Instead, a set
of candidate plans are generated, and a winner is chosen without consulting
the plan cache. Furthermore, explain prevents the MongoDB query planner
from caching the winning plan.
Note
Only the most important output fields are shown on this page, and fields for internal use are not documented. The fields listed in the output are subject to change.
Explain Output Structure
The explain results present the query plans as a tree of stages.
The output structure can differ based on which query engine the
operation uses. Operations can use the classic query engine or the
slot-based execution query engine.
To see how the output structure can differ between the two execution engines, see the following examples:
winningPlan: { stage: <STAGE1>, ... inputStage: { stage: <STAGE2>, ... inputStage: { stage: <STAGE3>, ... } } },
winningPlan: { queryPlan: { stage: <STAGE1>, ... inputStage: { stage: <STAGE2>, ... inputStage: { stage: <STAGE3>, ... } } } slotBasedPlan: { ... } },
Each stage passes its resulting documents or index keys to the parent node. The leaf nodes access the collection or the indices. The internal nodes use the documents or the index keys that result from the child nodes. The root node indicates the stage that MongoDB ultimately derives the result set from.
Stages are descriptive of the operation. For example:
COLLSCANfor a collection scanIXSCANfor scanning index keysFETCHfor retrieving documentsGROUPfor grouping documentsSHARD_MERGEfor merging results from shardsSHARDING_FILTERfor filtering out orphan documents from shardsTS_MODIFYfor modifying a time series collectionBATCHED_DELETEfor multiple document deletions that are batched together internally (starting in MongoDB 6.1)EOFfor when a stage is end-of-streamEXPRESSstages for a limited set of queries that can bypass regular query planning to use optimized index scan plans (New in version 8.0.)EXPRESSstages can be one of the following:EXPRESS_CLUSTERED_IXSCANEXPRESS_DELETEEXPRESS_IXSCANEXPRESS_UPDATE
Explain Output for MongoDB 5.1 and Later
This section shows the explain output for MongoDB 5.1 and later. To
see the explain output for older versions of MongoDB, refer to the
documentation for that version.
explain.explainVersionInteger field.
explainVersionis the output format version for the plan, such as"1"or"2".New in version 5.1.
queryPlanner
explain.queryPlanner information details the plan selected by
the query optimizer.
These examples may combine the output structures of MongoDB's classic and slot-based execution engines. They are not meant to be representative. Your output may differ significantly.
For unsharded collections, explain returns the following
queryPlanner information:
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>, ] }
Starting in MongoDB 8.0, the existing queryHash field is duplicated
in a new field named planCacheShapeHash. If you're using an earlier
MongoDB version, you'll only see the queryHash field. Future MongoDB
versions will remove the deprecated queryHash field, and you'll need
to use the planCacheShapeHash field instead.
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>, 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>, ] } ] } } }
Starting in MongoDB 8.0, the existing queryHash field is duplicated
in a new field named planCacheShapeHash. If you're using an earlier
MongoDB version, you'll only see the queryHash field. Future MongoDB
versions will remove the deprecated queryHash field, and you'll need
to use the planCacheShapeHash field instead.
explain.queryPlannerContains information on the selection of the query plan by the query optimizer.
explain.queryPlanner.namespaceA string that specifies the namespace with the names of the database and the collection accessed by the query. The namespace has the format
<database>.<collection>.
explain.queryPlanner.indexFilterSetA boolean that specifies whether MongoDB applied an index filter for the plan cache query shape.
explain.queryPlanner.querySettingsIf query settings are set,
querySettingscontains details about the query settings that are applied to the query shape.To add query settings and explore examples, which include
explain()output withquerySettings, seesetQuerySettings.New in version 8.0.
explain.queryPlanner.planCacheShapeHashStarting in MongoDB 8.0, the existing
queryHashfield is duplicated in a new field namedplanCacheShapeHash. If you're using an earlier MongoDB version, you'll only see thequeryHashfield. Future MongoDB versions will remove the deprecatedqueryHashfield, and you'll need to use theplanCacheShapeHashfield instead.A hexadecimal string that represents the hash of the plan cache query shape and is dependent only on the plan cache query shapes.
planCacheShapeHashcan help identify slow queries (including the query filter of write operations) with the same plan cache query shape.Note
As with any hash function, two different plan cache query shapes may result in the same hash value. However, the occurrence of hash collisions between different plan cache query shapes is unlikely.
For more information on
planCacheShapeHashandplanCacheKey, see planCacheShapeHash and planCacheKey.
explain.queryPlanner.planCacheKeyA hash of the key for the plan cache entry associated with the query.
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.For more information on
planCacheShapeHashandplanCacheKey, see planCacheShapeHash and planCacheKey.
explain.queryPlanner.optimizationTimeMillisTime in milliseconds the query planner spent on query optimization. This result doesn't include time spent optimizing inner
$lookupqueries.
explain.queryPlanner.optimizedPipelineA boolean that indicates that the entire aggregation pipeline operation was optimized away, and instead, fulfilled by a tree of query plan execution stages.
For example, the following aggregation operation can be fulfilled by the tree of query plan execution rather than using the aggregation pipeline.
db.example.aggregate([ { $match: { someFlag: true } } ] ) The field is only present if the value is
trueand only applies to explain on aggregation pipeline operations. Whentrue, because the pipeline was optimized away, no aggregation stage information appears in the output.
explain.queryPlanner.winningPlanA document that details the plan selected by the query optimizer.
explain.queryPlanner.winningPlan.stageA string that denotes the name of the stage.
Each stage consists of information specific to the stage. For example, an
IXSCANstage includes the index bounds along with other data specific to the index scan. If a stage has a child stage or multiple child stages, the stage will have aninputStageorinputStages.This field appears if the operation used the classic query execution engine.
explain.queryPlanner.winningPlan.typeIf
stageis set to"EOF",typeis a string that denotes the reason for the EOF stage:"nonExistentNamespace": indicates the query namespace does not exist."predicateEvalsToFalse": indicates that expression simplification determines that the query will not match any documents.
explain.queryPlanner.winningPlan.inputStageA document that describes the child stage, which provides the documents or index keys to its parent. The field is present if the parent stage has only one child.
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.
This field appears if the operation used the classic query execution engine.
explain.queryPlanner.winningPlan.isCachedA boolean that indicates if the winningPlan is in the plan cache.
This field is
truefor a maximum of one plan between the winning plan and the rejected plans. If the query has no cached plan, the field isfalsefor the winning plan and the rejected plans.
explain.queryPlanner.winningPlan.queryPlanA document that details the plan selected by the query optimizer. MongoDB presents the plan as a tree of stages.
This document appears if the query used the slot-based execution query engine.
New in version 5.1.
explain.queryPlanner.winningPlan.queryPlan.stageA string that denotes the name of the stage.
Each stage consists of information specific to the stage. For example, an
IXSCANstage includes the index bounds along with other data specific to the index scan.
explain.queryPlanner.winningPlan.queryPlan.typeIf
stageis set to"EOF",typeis a string that denotes the reason for the EOF stage:"nonExistentNamespace": indicates the query namespace does not exist."predicateEvalsToFalse": indicates that expression simplification determines that the query will not match any documents.
explain.queryPlanner.winningPlan.queryPlan.planNodeIdUnique integer field that identifies each stage in the execution plan. Field is included in all stages throughout the
explainresults.New in version 5.1.
explain.queryPlanner.winningPlan.slotBasedPlanDocument with information about the slot-based query execution plan tree and stages. For internal use by MongoDB.
New in version 5.1.
explain.queryPlanner.winningPlan.slotBasedPlan.stagesString that includes information on each stage in the slot-based query execution plan, including execution order, operations, and slot assignments. For internal use by MongoDB.
Starting in MongoDB 8.0, if a query uses block processing,
block_to_rowandts_bucket_to_cellblockappear in thestagesoutput.Changed in version 8.0.
explain.queryPlanner.rejectedPlansArray of candidate plans considered and rejected by the query optimizer. The array can be empty if there were no other candidate plans.
Rejected plans have the same fields as
explain.queryPlanner.winningPlan.Starting in MongoDB 8.0, rejected query plans only contain the
findportion of the query. In previous versions, rejected plans can contain aggregation stages like$group. Those aggregation stages aren't used by the query planner to choose the winning plan, so therejectedPlansfield only contains the portion of the query that was used to choose the winning plan.
executionStats
The returned explain.executionStats information details the
execution of the winning plan. In order to include
executionStats in the results, you must run the explain in either:
allPlansExecution verbosity mode. Use
allPlansExecutionmode to include partial execution data captured during plan selection.
These examples may combine the output structures of MongoDB's classic and slot-based execution engines. They are not meant to be representative. Your output may differ significantly.
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>, 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>, ... inputStage: { ... } } }, allPlansExecution: [ { nReturned: <int>, executionTimeMillisEstimate: <int>, totalKeysExamined: <int>, totalDocsExamined:<int>, 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> } }
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>, 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>, ... 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.executionStatsContains statistics that describe the completed query execution for the winning plan. For write operations, completed query execution refers to the modifications that would be performed, but does not apply the modifications to the database.
explain.executionStats.nReturnedNumber of documents returned by the winning query plan.
nReturnedcorresponds to thenfield returned bycursor.explain()in earlier versions of MongoDB.
explain.executionStats.executionTimeMillisTotal time in milliseconds required for query plan selection and query execution. It includes the time it takes to run the trial phase part of the plan selection process, but does not include the network time to transmit the data back to the client.
The time reported by
explain.executionStats.executionTimeMillisis not necessarily representative of actual query time. During steady state operations (when the query plan is cached), or when usingcursor.hint()withcursor.explain(), MongoDB bypasses the plan selection process, resulting in a faster actual time, leading to a lowerexplain.executionStats.executionTimeMillisvalue.
explain.executionStats.totalKeysExaminedNumber of index entries scanned.
explain.executionStats.totalKeysExaminedcorresponds to thenscannedfield returned bycursor.explain()in earlier versions of MongoDB.
explain.executionStats.totalDocsExaminedNumber of documents examined during query execution. Common query execution stages that examine documents are
COLLSCANandFETCH.Note
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.executionStagesDetails the completed execution of the winning plan as a tree of stages; i.e. a stage can have an
inputStageor multipleinputStages.Starting in MongoDB 5.1, a stage can have these input stages:
thenStageelseStageinnerStageouterStage
Each stage consists of execution information specific to the stage.
explain.executionStats.executionStages.executionTimeMillisEstimateThe estimated amount of time in milliseconds for query execution.
explain.executionStats.executionStages.opensStarting in MongoDB 5.1, the number of times a stage was opened during query execution.
explain.executionStats.executionStages.closesStarting in MongoDB 5.1, the number of times a stage was closed during query execution.
explain.executionStats.executionStages.worksSpecifies the number of "work units" performed by the query execution stage. Query execution divides its work into small units. A "work unit" might consist of examining a single index key, fetching a single document from the collection, applying a projection to a single document, or doing a piece of internal bookkeeping.
This field appears if the operation used the classic query execution engine.
explain.executionStats.executionStages.saveStateThe number of times that the query stage suspended processing and saved its current execution state, for example in preparation for yielding its locks.
explain.executionStats.executionStages.restoreStateThe number of times that the query stage restored a saved execution state, for example after recovering locks that it had previously yielded.
explain.executionStats.executionStages.isEOFSpecifies whether the execution stage has reached end of stream:
If
trueor1, the execution stage has reached end-of-stream.If
falseor0, the stage may still have results to return. For example, consider a query with a limit whose execution stages consists of aLIMITstage with an input stage ofIXSCANfor the query. If the query returns more than the specified limit, theLIMITstage will reportisEOF: 1, but its underlyingIXSCANstage will reportisEOF: 0.
explain.executionStats.executionStages.opTypeFor operations on time series collections, the type of operation.
explain.executionStats.executionStages.bucketFilterFor operations on time series collections, the filter used to reduce the number of buckets queried in the bucket catalog.
explain.executionStats.executionStages.residualFilterFor operations on time series collections, the filter used to query the bucket catalog.
explain.executionStats.executionStages.nBucketsUnpackedFor operations on time series collections, the number of buckets unpacked to resolve the operation.
explain.executionStats.executionStages.nMeasurementsDeletedFor operations on time series collections, the number of documents deleted.
explain.executionStats.executionStages.nMeasurementsInsertedFor operations on time series collections, the number of documents inserted.
explain.executionStats.executionStages.nMeasurementsMatchedFor operations on time series collections, the number of documents matched.
explain.executionStats.executionStages.nMeasurementsModifiedFor operations on time series collections, the number of documents modified.
explain.executionStats.executionStages.nMeasurementsUpsertedFor operations on time series collections, the number of documents upserted.
explain.executionStats.executionStages.inputStageEach
inputStagecan have different fields depending on the value ofinputStage.stage. The following table describes possible fields and what stages they can appear in.Each
inputStagecan have anotherinputStageas a field. See Explain Output Structure.FieldDescriptionApplicable StagesdocsExaminedSpecifies the number of documents scanned during the query execution stage.
COLLSCAN,FETCHkeysExaminedFor query execution stages that scan an index
keysExaminedis the total number of in-bounds and out-of-bounds keys that are examined in the process of the index scan. If the index scan consists of a single contiguous range of keys, only in-bounds keys need to be examined. If the index bounds consists of several key ranges, the index scan execution process may examine out-of-bounds keys in order to skip from the end of one range to the beginning of the next.IXSCANnumReadsThe number of documents scanned or index keys examined during the query execution stage.
New in version 5.1.
COLLSCAN,IXSCANseeksThe number of times that we had to seek the index cursor to a new position in order to complete the index scan.
IXSCANusedDiskWhether the stage wrote to disk.
New in version 5.3.
GROUPspillsThe number of times the stage spilled to disk.
New in version 8.2.
GROUP,SORTspilledBytesThe total amount of data written to disk in bytes.
New in version 8.2.
GROUP,SORTspilledRecordsThe total number of individual records spilled to disk.
New in version 8.2.
GROUP,SORTspilledDataStorageSizeThe total disk space, in bytes, used by the spilled data.
New in version 8.2.
GROUP,SORT
explain.executionStats.allPlansExecutionContains partial execution information captured during the plan selection phase for both the winning and rejected plans. The field is present only if
explainruns inallPlansExecutionverbosity mode.
explain.executionStats.operationMetricsContains resource consumption statistics, as long as they are not zero. The field is present only if
explainruns inexecutionStatsverbosity mode or higher and ifprofileOperationResourceConsumptionMetricsis enabled.Warning
MongoDB 8.2 removes
profileOperationResourceConsumptionMetrics. Therefore, code depending on operationMetrics does not work.
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 host: <string>, port: <int>, version: <string>, gitVersion: <string> } ...
Execution Plan Statistics for Query with $lookup Pipeline Stage
New in version 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:
The following fields are included in the explain results for a
$lookup query:
'$lookup': { from: <string>, as: <string>, localField: <string>, foreignField: <string> }, totalDocsExamined: <long>, totalKeysExamined: <long>, collectionScans: <long>, indexesUsed: [ <string_1>, <string_2>, ..., <string_n> ], executionTimeMillisEstimate: <long>
To see the descriptions for the fields in the $lookup section, see
the $lookup page.
The other fields are:
Execution Plan Statistics for Search Queries
New in version 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 returns execution statistics for search and vector search queries that use the classic engine only.
For more details on search and vector search query explain results, see:
Collection Scan
If the query planner selects a collection scan, the explain result
includes a COLLSCAN stage.
If the query planner selects an index, the explain result includes a
IXSCAN stage. The stage includes information such as the index
key pattern, direction of traversal, and index bounds.
Starting in MongoDB 5.3, if the query planner selects a clustered
index for a clustered
collection and the query contains bounds that
define the portion of the index to search, the explain result includes a
CLUSTERED_IXSCAN stage. The stage includes information about the
clustered index key and index bounds.
If the query planner selects a clustered index for a clustered collection and the query does not contain bounds, the
query performs an unbounded collection scan and the explain result
includes a COLLSCAN stage.
Note
The notablescan parameter does not allow unbounded
queries that use a clustered index because the queries require a
full collection scan.
For more information on execution statistics of collection scans, see Interpret Explain Plan Results.
Covered Queries
When an index covers a query, MongoDB can both match the query conditions and return the results using only the index keys. MongoDB does not need to examine documents from the collection to perform any part of the query.
When an index covers a query, the explain result has an IXSCAN
stage that is not a descendant of a FETCH stage, and in the
executionStats, the explain.executionStats.totalDocsExamined
is 0.
$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', ... }, ... ] }
In previous versions of MongoDB, cursor.explain() returned the
clauses array that detailed the indexes.
$sort and $group Stages
When explain is run in either
executionStats or
allPlansExecution verbosity
mode, the $sort and $group stages have
additional output.
Stage | Field | Type | Description |
|---|---|---|---|
| long | An estimated number of bytes processed in the | |
| boolean | Whether the | |
| long long | The number of times the | |
| long long | An estimate of the number of bytes written to disk in the
| |
| long long | The total number of individual records spilled to disk. | |
| long long | The total disk space, in bytes, used by the spilled data. | |
| boolean | Whether the | |
| long long | The number of times the | |
| long long | An estimate of the number of bytes written to disk in the
| |
| long long | The total number of individual records spilled to disk. | |
| long long | The total disk space, in bytes, used by the spilled data. |
Sort Stage
If MongoDB cannot use an index or indexes to obtain the sort order, the
results include a SORT stage indicating an in-memory sort operation.
If the explain plan does not contain an explicit SORT stage, then MongoDB used
an index to obtain the sort order.
Query Shape Hash
Starting in MongoDB 8.0, explain outputs the following field:
explain.queryShapeHashA hexadecimal string that represents the hash of the query shape. For more information, see Query Shapes.
New in version 8.0.