この章では、MongoDBのクエリパフォーマンス解析について紹介します。SQLのexplainと同様に、MongoDBもクエリ文のパフォーマンスを解析するためのexplainをサポートしています。
基本的な使用方法
explain関数を呼び出すことで、解析結果を取得できます。
// findメソッドの解析結果
db.collection.find({}).explain();
// aggregateメソッドの解析結果
db.collection.explain().aggregate([]);
explainには3つのモードがあります:
- queryPlanner (デフォルト)
- executionStats
- allPlansExecution
説明:
- queryPlanner を使用すると、実際のステートメントを実行せず、すべての可能な実行計画をリストアップし、すでに勝利した winningPlan プランを表示します。
- executionStats を使用すると、winningPlan プランのみを実行し、結果を出力します。
- allPlansExecution を使用すると、すべてのプランを実行し、結果を出力します。
異なるモードの使用方法
// executionStats モード、explain関数にパラメータを単純に渡す
db.collection.find({}).explain('executionStats');
// allPlansExecution モード
db.collection.find({}).explain('allPlansExecution');
explainコンテンツの説明
queryPlannerコンテンツ
以下の内容は、explainでデフォルトで返されるコンテンツで、非キー情報は無視します。
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.orders",
"indexFilterSet" : false, // キーメトリクス、インデックスによるデータフィルタリングの使用
"winningPlan" : {
"stage" : "COLLSCAN", // キーメトリクス、ステージフェーズの名前。各フェーズにはフェーズ固有の情報があり、COLLSCANはコレクション全体のスキャンを表します
"direction" : "forward"
},
"rejectedPlans" : [ ]
}
...
}
ステージフェーズの種類は以下の通りです:
- COLLSCAN: フルテーブルスキャン
- IXSCAN: インデックススキャン
- FETCH: インデックスを基に特定のドキュメントを取得
- SHARD_MERGE: 各シャードが返したデータをマージ
- SORT: メモリ内でのソーティング
- LIMIT: 返り値の数を制限
- SKIP: スキップして使用
- IDHACK: _id のクエリ
- SHARDING_FILTER: mongosを通じてシャード化されたデータをクエリ
- COUNT: db.coll.explain().count()など、カウント操作を使用した場合
- COUNTSCAN: カウントに非インデックスを使用していない場合のステージ
- COUNT_SCAN: カウントにインデックスを使用している場合のステージ
- SUBPLA: インデックスを使用していない$orクエリのステージ
- TEXT: フルテキストインデックスを使用したクエリのステージ
- PROJECTION: 返されるフィールドを制限するためのステージ
executionStatsコンテンツ
以下の内容は、executionStatsモードで返されるコンテンツで、非キー情報は無視します。
{
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 5, // 返されたドキュメントの数
"executionTimeMillis" : 0, // 実行時間
"totalKeysExamined" : 0, // スキャンされたインデックスの数
"totalDocsExamined" : 5, // スキャンされたドキュメントの合計数
"executionStages" : {
"stage" : "COLLSCAN", // ステージタイプ、COLLSCANはテーブル全体をスキャンすることを意味します
"nReturned" : 5,
"executionTimeMillisEstimate" : 0,
"works" : 7,
"advanced" : 5,
"needTime" : 1,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"direction" : "forward",
"docsExamined" : 5
}
}
}
クエリの最適化アイデア
- 可能な限りインデックスを使用する
- スキャンされるドキュメント数をできるだけ少なくする