mongodbクエリ文効率分析
6618 ワード
準備作業
db.test.createIndex( { a: -1, b:-1 }, {name:"ab"})
{_id:1, a:1, b:2}
{_id:2, a:1, b:2}
{_id:3, a:1, b:3}
{_id:4, a:1, b:3}
{_id:5, a:2, b:2}
{_id:6, a:2, b:2}
{_id:7, a:2, b:3}
{_id:8, a:2, b:3}
インデックス解析 db.test.find({a:1}).explain();
実行結果{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "local.test",
"indexFilterSet" : false,
"parsedQuery" : {
"a" : {
"$eq" : 1.0
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"a" : -1.0,
"b" : -1.0
},
"indexName" : "ab",
"isMultiKey" : false,
"multiKeyPaths" : {
"a" : [],
"b" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"a" : [
"[1.0, 1.0]"
],
"b" : [
"[MaxKey, MinKey]"
]
}
}
},
"rejectedPlans" : []
},
"serverInfo" : {},
"ok" : 1.0
}
キーパラメータの説明
フィールド
説明
queryPlanner.indexFilterSet index filter
が有効になっているかどうか、mongodbはindex filter
を使用してインデックスを選択します.
queryPlanner.winningPlan
オプティマイザが最終的に選択したplan
queryPlanner.winningPlan.inputStage
入力パラメータとインデックスのクエリー
queryPlanner.winningPlan.inputStage.stage
フェーズCOLLSCAN
:スキャンcollection IXSCAN
スキャンインデックスFETCH
ドキュメントを読み込む
queryPlanner.winningPlan.inputStage.keyPattern
索引の書式は、索引の作成時の書式と一致します.
queryPlanner.winningPlan.inputStage.indexBounds
クエリー条件の制約値
queryPlanner.rejectedPlans
拒否された候補plan
プロセス分析の実行 db.test.find({a:1}).explain("executionStats");
{
"queryPlanner" : { },
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 4,
"executionTimeMillis" : 0,
"totalKeysExamined" : 4,
"totalDocsExamined" : 4,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 4,
"executionTimeMillisEstimate" : 0,
"works" : 5,
"advanced" : 4,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 4,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 4,
"executionTimeMillisEstimate" : 0,
"works" : 5,
"advanced" : 4,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"a" : -1.0,
"b" : -1.0
},
"indexName" : "ab",
"isMultiKey" : false,
"multiKeyPaths" : {
"a" : [],
"b" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"a" : [
"[1.0, 1.0]"
],
"b" : [
"[MaxKey, MinKey]"
]
},
"keysExamined" : 4,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"serverInfo" : {},
"ok" : 1.0
}
キーフィールドの説明
フィールド
説明
executionStats.totalKeysExamined
インデックスの遍歴回数
executionStats.totalDocsExamined
ドキュメントを巡回する回数
executionTimeMillisEstimate
実行時間の予測
遍歴の回数が多ければ多いほど、遍歴は遅くなるに違いない.この例ではインデックスを使用し、条件を満たす4つのドキュメントがあり、すべての遍歴回数は4である.
インデックスを使用しない db.test.find({b:2}).explain("executionStats");
{
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 4,
"executionTimeMillis" : 0,
"totalKeysExamined" : 0,
"totalDocsExamined" : 8,
},
}
db.test.find({b:2})はインデックス{a:1, b:1}
を使用できないため、インデックスを巡回せずにcollection全体を巡回します.
インデックスデータのみを返す db.test.find({a:2}, {_id:0, a:1, b:1}).explain("executionStats");
{
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 4,
"executionTimeMillis" : 0,
"totalKeysExamined" : 4,
"totalDocsExamined" : 0,
}
},
}
この例ではmongodbはa
,b
の2回のフィールドしか返さないが、この2つのフィールドはちょうどインデックスを作成するのでdocumentを読み取る必要がないので、ドキュメントを遍歴しない.
まとめ
mongodbのインデックスはmysqlのインデックスとよく似ています
db.test.find({a:1}).explain();
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "local.test",
"indexFilterSet" : false,
"parsedQuery" : {
"a" : {
"$eq" : 1.0
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"a" : -1.0,
"b" : -1.0
},
"indexName" : "ab",
"isMultiKey" : false,
"multiKeyPaths" : {
"a" : [],
"b" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"a" : [
"[1.0, 1.0]"
],
"b" : [
"[MaxKey, MinKey]"
]
}
}
},
"rejectedPlans" : []
},
"serverInfo" : {},
"ok" : 1.0
}
db.test.find({a:1}).explain("executionStats");
{
"queryPlanner" : { },
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 4,
"executionTimeMillis" : 0,
"totalKeysExamined" : 4,
"totalDocsExamined" : 4,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 4,
"executionTimeMillisEstimate" : 0,
"works" : 5,
"advanced" : 4,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 4,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 4,
"executionTimeMillisEstimate" : 0,
"works" : 5,
"advanced" : 4,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"a" : -1.0,
"b" : -1.0
},
"indexName" : "ab",
"isMultiKey" : false,
"multiKeyPaths" : {
"a" : [],
"b" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"a" : [
"[1.0, 1.0]"
],
"b" : [
"[MaxKey, MinKey]"
]
},
"keysExamined" : 4,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"serverInfo" : {},
"ok" : 1.0
}
キーフィールドの説明
フィールド
説明
executionStats.totalKeysExamined
インデックスの遍歴回数
executionStats.totalDocsExamined
ドキュメントを巡回する回数
executionTimeMillisEstimate
実行時間の予測
遍歴の回数が多ければ多いほど、遍歴は遅くなるに違いない.この例ではインデックスを使用し、条件を満たす4つのドキュメントがあり、すべての遍歴回数は4である.
インデックスを使用しない db.test.find({b:2}).explain("executionStats");
{
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 4,
"executionTimeMillis" : 0,
"totalKeysExamined" : 0,
"totalDocsExamined" : 8,
},
}
db.test.find({b:2})はインデックス{a:1, b:1}
を使用できないため、インデックスを巡回せずにcollection全体を巡回します.
インデックスデータのみを返す db.test.find({a:2}, {_id:0, a:1, b:1}).explain("executionStats");
{
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 4,
"executionTimeMillis" : 0,
"totalKeysExamined" : 4,
"totalDocsExamined" : 0,
}
},
}
この例ではmongodbはa
,b
の2回のフィールドしか返さないが、この2つのフィールドはちょうどインデックスを作成するのでdocumentを読み取る必要がないので、ドキュメントを遍歴しない.
まとめ
mongodbのインデックスはmysqlのインデックスとよく似ています
db.test.find({b:2}).explain("executionStats");
{
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 4,
"executionTimeMillis" : 0,
"totalKeysExamined" : 0,
"totalDocsExamined" : 8,
},
}
db.test.find({a:2}, {_id:0, a:1, b:1}).explain("executionStats");
{
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 4,
"executionTimeMillis" : 0,
"totalKeysExamined" : 4,
"totalDocsExamined" : 0,
}
},
}
この例ではmongodbは
a
,b
の2回のフィールドしか返さないが、この2つのフィールドはちょうどインデックスを作成するのでdocumentを読み取る必要がないので、ドキュメントを遍歴しない.