explain の結果
項目一覧
クエリプラン とクエリプランの実行統計に関する情報を返すために、MongoDB は以下を提供します。
cursor.explain()
メソッド、およびexplain
コマンド
explain
の結果は、クエリプランがステージのツリーとして表示されます。
"winningPlan" : { "stage" : <STAGE1>, ... "inputStage" : { "stage" : <STAGE2>, ... "inputStage" : { "stage" : <STAGE3>, ... } } },
各ステージはその結果を渡します(つまり、 ドキュメントまたはインデックス キー)を親ノードに適用します。 リーフ ノードはコレクションまたはインデックスにアクセスします。 内部ノードは、子ノードから生成されたドキュメントまたはインデックス キーを操作します。 ルート ノードは、MongoDB が結果セットを導き出す最終ステージです。
ステージは、操作について説明しています。例:
COLLSCAN
、コレクションスキャン用IXSCAN
、インデックス キーのスキャン用FETCH
、ドキュメント検索用SHARD_MERGE
シャードからの結果のマージ用SHARDING_FILTER
、シャードから孤立したドキュメントのフィルタリング用
Explain の出力
次のセクションでは、 explain
操作によって返されるいくつかのキー フィールドのリストを示します。
注意
フィールドのリストは網羅的なものではなく、explain の以前のバージョンからのキー フィールドの変更を強調表示することを目的としています。
出力形式は、リリース間で変更される可能性があります。
queryPlanner
queryPlanner
情報には、クエリオプティマイザによって選択されたプランの詳細が示されます。
シャーディングされていないコレクションの場合、explain
は次の queryPlanner
情報を返します。
"queryPlanner" : { "plannerVersion" : <int>, "namespace" : <string>, "indexFilterSet" : <boolean>, "parsedQuery" : { ... }, "queryHash" : <hexadecimal string>, "planCacheKey" : <hexadecimal string>, "optimizedPipeline" : <boolean>, // Starting in MongoDB 4.2, only appears if true "winningPlan" : { "stage" : <STAGE1>, ... "inputStage" : { "stage" : <STAGE2>, ... "inputStage" : { ... } } }, "rejectedPlans" : [ <candidate plan 1>, ... ] }
シャーディングされたコレクションの場合、explain
には shards
フィールドの各アクセスされたシャード向けの主要クエリ プランナーとサーバーに関する情報が含まれます。
"queryPlanner" : { "mongosPlannerVersion" : <int>, "winningPlan" : { "stage" : <STAGE1>, "shards" : [ { "shardName" : <string>, "connectionString" : <string>, "serverInfo" : { "host" : <string>, "port" : <int>, "version" : <string>, "gitVersion" : <string> }, "plannerVersion" : <int>, "namespace" : <string>, "parsedQuery" : <document>, "queryHash" : <hexadecimal string>, "planCacheKey" : <hexadecimal string>, "optimizedPipeline" : <boolean>, // Starting in MongoDB 4.2, only appears if true "winningPlan" : { "stage" : <STAGE2>, "inputStage" : { "stage" : <STAGE3> ..., } }, rejectedPlans: [ <candidate plan1>, ] } ] } }
explain.queryPlanner
クエリオプティマイザによるクエリプランの選択に関する情報が含まれています。
explain.queryPlanner.namespace
クエリによってアクセスされるデータベースとコレクションの名前を含む名前空間を指定する文字列です。名前空間の形式は
<database>.<collection>
です。
explain.queryPlanner.indexFilterSet
MongoDB でクエリシェイプにインデックス フィルターが適用されたかどうかを指定するブール値。
explain.queryPlanner.queryHash
クエリシェイプのハッシュを表す 16 進数の文字列で、クエリシェイプのみに依存します。
queryHash
は、同じクエリシェイプでもスロー クエリ(書き込み (write) 操作のクエリフィルターを含む)を識別するのに役立ちます。注意
他のハッシュ関数と同様に、2 つの異なるクエリシェイプで同じハッシュ値が生成される場合があります。ただし、異なるクエリシェイプ間でハッシュ衝突が発生する可能性は低くなります。
queryHash
とplanCacheKey
の詳細については、「queryHash
とplanCacheKey
」を参照してください。バージョン 4.2の新機能
explain.queryPlanner.planCacheKey
クエリに関連付けられたプラン キャッシュ エントリのキーのハッシュです。
queryHash
と違ってplanCacheKey
は、クエリシェイプとそのシェイプで現在使用可能なインデックスの両方の関数です。具体的には、クエリシェイプをサポート可能なインデックスが追加または削除された場合、planCacheKey
値は変化しますが、queryHash
の値は変化しません。queryHash
とplanCacheKey
の詳細については、「queryHash
とplanCacheKey
」を参照してください。バージョン 4.2の新機能
explain.queryPlanner.optimizedPipeline
集計パイプライン操作全体が最適化され、クエリプランの実行ステージをツリー形式に体系化して実行されるようになったことを示すブール値。
たとえば、次の集計操作は集計パイプラインを使用するのではなく、クエリプラン実行のツリーで実行できます。
db.example.aggregate([ { $match: { someFlag: true } } ] ) このフィールドは、値が
true
の場合にのみ表示され、集計パイプライン操作を説明する目的でのみ適用されます。値をtrue
に設定すると、パイプラインが最適化されたため、集計ステージ情報は出力に表示されません。バージョン 4.2の新機能
explain.queryPlanner.winningPlan
クエリオプティマイザによって選択されたプランの詳細が記載されたドキュメントです。 MongoDB では、プランはステージのツリーとして表示されます。つまり、ステージには
inputStage
を含めることができます。また、ステージに複数の子ステージがある場合は、inputStages
を含めることができます。explain.queryPlanner.winningPlan.stage
ステージ名を示す文字列。
各ステージは、ステージに固有の情報で構成されます。 たとえば、
IXSCAN
ステージには、インデックスの限界と、インデックス スキャンに固有の他のデータが含まれます。 ステージに子ステージが 1 つまたは複数ある場合、そのステージには inputStage または inputStages が含まれます。
executionStats
返されたexecutionStats
情報には、当選プランの実行の詳細が表示されます。 結果にexecutionStats
を含めるには、次のいずれかで explain を実行する必要があります。
allPlansExecution の冗長モードです。プラン選択中にキャプチャされた部分的な実行データを含めるには、
allPlansExecution
モードを使用します。
シャーディングされていないコレクションの場合、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" : { "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
当選プランの完了したクエリ実行を示す統計が含まれます。書込み (write) 操作の場合、完了したクエリの実行とは、実行される予定の変更を指しますが、変更はデータベースに適用されません。
explain.executionStats.nReturned
当選したクエリプランが返したドキュメントの数。
nReturned
は、MongoDB の以前のバージョンでcursor.explain()
によって返されたn
フィールドに対応しています。
explain.executionStats.executionTimeMillis
クエリプランの選択とクエリの実行に必要な合計時間(ミリ秒)。これには、プラン選択プロセスの試用段階を実行する時間は含まれるが、データをクライアントに送り返すためのネットワーク時間は含まれません。
explain.executionStats.executionTimeMillis
によって報告される時間は、必ずしも実際のクエリ時間を表していません。定常状態の操作中(クエリプランがキャッシュされている場合)、またはcursor.hint()
をcursor.explain()
とともに使用している場合、MongoDB はプラン選択プロセスをバイパスし、実際の時間が短縮されてexplain.executionStats.executionTimeMillis
値が低くなります。
explain.executionStats.totalKeysExamined
スキャンされたインデックスエントリの数。
totalKeysExamined
は、MongoDB の以前のバージョンでcursor.explain()
によって返されたnscanned
フィールドに対応しています。
explain.executionStats.totalDocsExamined
クエリの実行中に検査されたドキュメントの数。ドキュメントを検査する一般的なクエリ実行ステージは、
COLLSCAN
とFETCH
です。注意
totalDocsExamined
は、返されたドキュメント数ではなく、検査されたドキュメントの合計数を示します。たとえば、ステージではフィルターを適用するためにドキュメントを調べることができます。ドキュメントがフィルターで除外された場合、そのドキュメントは検査済みですが、クエリ結果セットの一部として返されません。クエリの実行中にドキュメントが複数回検査された場合、
totalDocsExamined
はそれぞれの検査でカウントします。 つまり、totalDocsExamined
は検査された一意のドキュメントの合計数ではありません。
explain.executionStats.executionStages
当選プランの実行が完了したことをステージのツリーとして表示します。つまり、1 つのステージに 1 つの
inputStage
または複数のinputStages
があってもかまいません。各ステージは、ステージに固有の実行情報で構成されます。
explain.executionStats.executionStages.works
クエリ実行ステージで実行される「ワーク ユニット」の数を指定します。クエリの実行では、作業が小さな単位に分割されます。「ワークユニット」には、1 つのインデックス キーの調査、コレクションから 1 つのドキュメントの取り出し、1 つのドキュメントにプロジェクションを適用、あるいは、内部ブックキーピングの実行で構成される場合があります。
explain.executionStats.executionStages.needTime
中間結果を親ステージに進めなかった作業サイクルの数(
explain.executionStats.executionStages.advanced
を参照)。 たとえば、インデックス スキャン ステージでは、インデックス キーを返すのではなく、インデックス内の新しい位置を探すのにワークサイクルが費やされる場合があります。このワーク サイクルはexplain.executionStats.executionStages.advanced
ではなくexplain.executionStats.executionStages.needTime
にカウントさます。
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
インデックスをスキャンするクエリ実行ステージ(例: IXCAN)、
keysExamined
はインデックス スキャンのプロセスで検査される限界内のキーと限界外のキーの総数です。 インデックス スキャンが 1 つの連続したキー範囲で構成されている場合は、範囲内のキーのみを調べる必要があります。 インデックスの限界が複数のキー範囲で構成されている場合、インデックス スキャンの実行プロセスでは、ある範囲の終わりから次の範囲の先頭にスキップするために、範囲外のキーを調べることがあります。次の例を考えてみましょう。フィールド
x
のインデックスがあり、 コレクションにはx
値1から100までの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.allPlansExecution
当選したプランと拒否されたプランの両方について、プラン選択フェーズ中にキャプチャされた部分的な実行情報が含まれます。このフィールドは、
explain
がallPlansExecution
冗長モードで実行されている場合にのみ存在します。
パイプライン ステージを使用するクエリの実行プラン統計$lookup
バージョン 5.0 で追加
explain の結果には、$lookup
のパイプライン ステージを使用するクエリの実行統計を含めることができます。これらの実行統計を含めるには、以下のいずれかの実行冗長モードで説明操作を実行する必要があります。
$lookup
クエリの explain の結果には次のフィールドが含まれます。
'$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
ページを参照してください。
その他のフィールドは次のとおりです。
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> } ...
3.0形式の変更
MongoDB 3.0以降、 explain
結果の形式とフィールドは以前のバージョンから変更されています。 以下に、重要な違いをいくつか示します。
コレクションスキャンとインデックスの使用
クエリ プランナーがコレクションスキャンを選択した場合、explain の結果には COLLSCAN
ステージが含まれます。
クエリ プランナーによってインデックスが選択された場合、explain の結果には IXSCAN
ステージが加わります。このステージでは、インデックス キーのパターン、トラバースの方向、インデックスの限界などの情報が提供されます。
MongoDB の以前のバージョンでは、 cursor.explain()
は次の値を持つcursor
フィールドを返しました。
BasicCursor
、コレクションスキャン用、BtreeCursor <index name> [<direction>]
インデックス スキャン用。
コレクションスキャンとインデックススキャンの実行統計の詳細については、「クエリパフォーマンスの分析 」を参照してください。
カバード クエリ
インデックスがクエリをカバーする場合、MongoDB ではクエリの条件を一致させること、およびインデックスキーのみを使用して結果を返すこともできます。MongoDBでは、クエリの一部を実行するためにコレクションのドキュメントを検査する必要はありません。
インデックスがクエリを補う場合、explain の結果には FETCH
ステージの子孫ではない、IXSCAN
ステージがあり、executionStats
では totalDocsExamined
は 0
です。
MongoDB の以前のバージョンでは、インデックスがクエリをカバーしているかどうかを示すために、 cursor.explain()
はindexOnly
フィールドを返しました。
インデックスの交差
インデックス交差プランの場合、結果にはインデックスの詳細を示すinputStages
配列を持つAND_SORTED
ステージまたはAND_HASH
ステージのいずれかが含まれます。例:
{ "stage" : "AND_SORTED", "inputStages" : [ { "stage" : "IXSCAN", ... }, { "stage" : "IXSCAN", ... } ] }
MongoDB の以前のバージョンでは、インデックス交差により、 cursor.explain()
はComplex Plan
の値を持つcursor
フィールドを返しました。
$or
式
MongoDB が $or
式にインデックスを使用する場合、結果にはインデックスの詳細を示す inputStages
配列を含む、OR
ステージが含まれます。以下がその例です。
{ "stage" : "OR", "inputStages" : [ { "stage" : "IXSCAN", ... }, { "stage" : "IXSCAN", ... }, ... ] }
MongoDB の以前のバージョンでは、cursor.explain()
インデックスの詳細を示す clauses
配列を返していました。
$sort
ステージと$group
ステージ
explain
が、executionStats または allPlansExecution 冗長モードのいずれかで実行されると、$sort
および $group
ステージに追加の出力があります。
ソート ステージ
MongoDB では、1 つまたは複数のインデックスを使用してソート順序を取得できない場合、結果にはブロッキングソート操作を指し示す SORT
ステージが含まれます。ブロッキングソートは、コレクションまたはデータベースに対する同時操作をブロックしません。この名前は、SORT
ステージが出力ドキュメントを返す前にすべての入力ドキュメントを読み取り、その特定のクエリのデータフローをブロックするという要件に由来しています。
MongoDB がブロッキングソート操作に 100 メガバイトを超えるシステム メモリを必要とする場合、クエリが cursor.allowDiskUse()
を指定しない限り、MongoDB はエラーを返します。cursor.allowDiskUse()
では、ブロッキングソート操作の処理中に、MongoDB がディスク上の一時ファイルを使用して、100 メガバイトのシステムメモリ制限を超えるデータを保存できるようにします。explain プランに明示的な SORT
ステージが含まれていない場合には、MongoDB はインデックスを使用して並べ替え順を取得できます。