、()、文の分析ツールを説明
MongoDBの3.0 +さんが説明し、3つのモードがありqueryPlanner
、すなわち:executionStats
、allPlansExecution
、。実際の開発、一般的に使用されるexecutionStats
モデル、このモデルの主な分析。
> db.getCollection('customer').find({"age":{"$lte":2000}}).explain("executionStats")
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "personmap.person",
"indexFilterSet" : false,
"parsedQuery" : {
"age" : {
"$lte" : 2000.0
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"age" : 1.0
},
"indexName" : "age_1",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"age" : [
"[-1.#INF, 2000.0]"
]
}
}
},
"rejectedPlans" : []
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 2001,
"executionTimeMillis" : 143,
"totalKeysExamined" : 2001,
"totalDocsExamined" : 2001,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 2001,
"executionTimeMillisEstimate" : 0,
"works" : 2002,
"advanced" : 2001,
"needTime" : 0,
"needFetch" : 0,
"saveState" : 16,
"restoreState" : 16,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 2001,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 2001,
"executionTimeMillisEstimate" : 0,
"works" : 2002,
"advanced" : 2001,
"needTime" : 0,
"needFetch" : 0,
"saveState" : 16,
"restoreState" : 16,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"age" : 1.0
},
"indexName" : "age_1",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"age" : [
"[-1.#INF, 2000.0]"
]
},
"keysExamined" : 2001,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0,
"matchTested" : 0
}
}
},
"serverInfo" : {
"host" : "qinxiongzhou",
"port" : 27017,
"version" : "3.0.7",
"gitVersion" : "6ce7cbe8c6b899552dadd907604559806aa2e9bd"
},
"ok" : 1.0
}
queryPlannerの分析
queryPlanner:返すqueryPlanner
queryPlanner.namespaceを:クエリによって返される値は、クエリのテーブルである
queryPlanner.indexFilterSet:クエリのためにそこにindexfilterかどうかを
クエリによって返されたクエリオプティマイザのための最適な実行計画の詳細は:queryPlanner.winningPlan 。
queryPlanner.winningPlan.stage:ステージ最適な実行計画、リターンがフェッチ、(ステージいくつかのモードで後で説明する)インデックス位置によって戻される特定の文書を取得するように理解することができます。
queryPlanner.winningPlan.inputStage:サブステージを記述するために使用され、親とインデックスキーのステージのドキュメントを提供します。
queryPlanner.winningPlan.stage子段は、ここでの表現は、インデックス・スキャンで、IXSCANです。
queryPlanner.winningPlan.keyPattern:インデックスはここに、コンテンツをスキャンしました:1、状態:1、 modify_time:-1 とSCID :. 1
queryPlanner.winningPlan.indexName:獲得プラン選択のインデックス。
queryPlanner.winningPlan.isMultiKeyは、インデックスが配列の上に構築された場合のリターンは、偽であるマルチキーは、あるかどうか、ここではそれは本当だろう。
queryPlanner.winningPlan.direction:この転送ここでクエリー配列に対してクエリ、使用する場合.sort({modify_time:-1})は後方に表示されます。
queryPlanner.winningPlan.indexBounds:winningplan範囲は、主に読み出したデータを、データを検索加速するchunckのMongoDBの中に直接配置されている[MaxKey、MinKey]、設定されていない場合、インデックス範囲スキャン。
queryPlanner.rejectedPlans:他の実施計画winningPlan特定情報の同じ感覚を返す詳細戻り、(非最適なクエリオプティマイザであるリジェクト)。
ExecutionStatsは、ドリルダウンする戻ります
第一層、executionTimeMillis
最も直感的な戻り値がexecutionTimeMillis値である説明は、この値は確かに可能な限りそのように少し期待し、私たちのために実行時間この声明を指します。
これは3 executionTimeMillis、すなわち:
executionStats.executionTimeMillis:クエリの全体的なクエリ時間;
executionStats.executionStages.executionTimeMillisEstimate:データを取得するための時間インデックス2001に応じて得られるクエリー文書;
executionStats.executionStages.inputStage.executionTimeMillisEstimate:問い合わせスキャン2001タイムライン指標
第二層、索引及び文書スキャニングとクエリの数は、エントリの数を返し
、クエリによって返されたエントリの記事、索引スキャンエントリ、原稿読取エントリを表す3つの返品アイテム、nReturned、totalKeysExamined、totalDocsExamined、に焦点を当てています。
これらは、視覚的にexecutionTimeMillisに影響を与えている、あまり我々はより速くスキャンする必要があります。
クエリのために、私たちの理想的な状態は次のとおりです。nReturned = totalKeysExamined = totalDocsExamined
三階、ステージ状態の分析
のでtotalKeysExaminedとtotalDocsExaminedへの影響は何ですか?ステージのタイプがあります。種類は以下のとおり:
COLLSCAN:全表スキャン
IXSCAN:インデックススキャン
FETCH:インデックスが指定されたドキュメント取得するために
SHARD_MERGE:それぞれのデータスライスがマージ返し
メモリにソートショー:SORT
LIMIT:制約の数は、使用制限を返し
SKIPを:スキップをスキップします
IDHACK:_idのためのクエリ
SHARDING_FILTER:データスライスmongosのクエリ
COUNT:()のカウント()操作など行う回数をdb.coll.explain使用。
COUNTSCAN:カウントインデックスを返すときに、ステージカウントが行われていない使用
COUNT_SCANました:インデックスの行動回数が戻ってきたときのステージを使用してカウント
$またはクエリを返すのインデックスステージには使用されません:SUBPLAを
TEXTを:フルテキストインデックスは、クエリ時間の戻り段階使用
PROJECTIONを:限られたフィールドへの復帰時にステージに戻り
、通常のクエリに、私が見たいのですが(索引を過ごすために可能な限りクエリ時間)の組み合わせをステージに:
+ IDHACKフェッチ
フェッチIXSCAN +
リミット+(+ IXSCANフェッチ)
PROJECTION + IXSCANを
+ IXSCAN SHARDING_FITER
COUNT_SCAN
COLLSCAN(全表スキャン)、SORT(ソートしかし、誰インデックスを使用して)、不合理なSKIPは、SUBPLA($または未使用のインデックス)、COUNTSCANは(インデックスを使用していない次の段階を含める見たいと思っていません実施回数)
第二に、インデックス操作
クエリインデックスの1セット
> db.getCollection('customer').getIndexes()
2、インデックスセットサイズを参照してください
> db.getCollection('customer').totalIndexSize()
3.通常のインデックスを作成します。
#1 表示升序,-1 表示降序
> db.customer.ensureIndex({"tags":1}) 或者
> db.customer.createIndex({"tags":1}) 或者
> db.getCollection('customer').createIndex({"tags":1})
4、ドキュメントのインデックス作成
> db.getCollection('customer').createIndex({"content.title":1, "content.judgementType":1}) 或者
> db.getCollection('customer').ensureIndex({"content.title":1, "content.judgementType":1}) 或者
> db.customer.createIndex({"content.title":1, "content.judgementType":1}) 或者
> db.customer.ensureIndex({"content.title":1, "content.judgementType":1})
#让创建索引的过程在后台运行
> db.getCollection('customer').createIndex({"content.title":1, "content.judgementType":1},{background:true})
5、ユニークインデックス
> db.customer.ensureIndex({"content.title":1, "content.judgementType":1},{unique: true})
6、インデックスの強制的使用
#hint 命令可以强制使用某个索引
> db.customer.find({age:{$lt:30}}).hint({name:1, age:1}).explain()
7、インデックスを削除
#删除集合所有索引
db.getCollection('customer').dropIndexes()
#删除集合指定索引
db.getCollection('customer').dropIndex('索引名')
第三に、注意を払います
1は、MongoDBのはオペレータの非効率性
「$場所」と「$が存在する」:この二つの演算子を、インデックスを使用することはできません。
「$ネ」:一般的に否定効率を話すことは比較的低いです。「$ね」クエリは、インデックスを使用しますが、非常に効果的ではないことができます。彼はむしろ「$ね」指定されたエントリよりも、索引エントリのすべてを見なければならないので、今回は彼がインデックス全体をスキャンする必要があります。
「$しない」:時々できインデックスを使用するために、彼は通常、インデックスを使用する方法を知りません。だから、ほとんどの場合、「$ません」全表スキャンに退化します。
「$ニン」:この演算子は、常に全表スキャンになります
2、またはクエリ
のMongoDBは、(少なくとも私が使用しているので、2.6である)クエリでのみインデックスを使用した場合は、{「X」:1}のインデックス{有する「Y」を:1}でインデックスがでもある{「X」:1、「 Y」:1} クエリが実行され、MongoDBの一つだけインデックスを使用しては、代わりに2つを使用します。「$かは、」実際には2回のクエリを実行し、その結果をマージするため、「$または」例外「$か」には、各単語のインデックスを使用することができます。
一般に、複数のクエリを、使用または統合の結果、単一のフィールドのための単一のクエリと同じくらい良い高効率、あなたはできるだけ多くの$を使用する必要があります。
図3は、MongoDBのクエリオプティマイザ
他のデータベースとのMongoDBクエリオプティマイザは少し異なります。インデックスが正確にクエリに一致することができれば、あなたのクエリに複数のインデックスがあるかもしれない正確に一致した場合、基本的に、クエリオプティマイザは、このインデックスを使用します。MongoDBは、それを選択する方法であることを?:MongoDBのクエリプランが返された最初の100の結果の実施と並行して複数のインデックスが勝者であるだろう、他のクエリプランは終了します。
この計画は、彼は次のような状況が再スケジュールされますが、このクエリを使用する次のバッファリングされます。
図4は、インデックスを使用しない場合
、データのより小さなサブセットを抽出する際、インデックスが(そうのみページ)非常に有効です。より高速なインデックスを使用していない一部のクエリがあります。クエリ効率遅く、元のセットに結果セットのシェアの割合が大きくなります。一度インデックス・エントリを検索し、インデックスへのポインタを適切なドキュメントを見つけるために:インデックスの使用は二度見する必要があるため。全表スキャンは、単一のクエリが必要です。最悪の場合に見て、インデックスが全表スキャン数の二倍になります。効率は、全表スキャンよりも大幅に低くなります。
残念ながら、インデックスサイズ、クエリがコレクション(またはそれ以上)での文書の30%を返却する必要がある場合、インデックスは、一般的には、便利である文書のサイズに応じて、それをテストする必要があると判断場合は厳密なルールは、私たちに教えていないがありますより速く行く全表スキャンとインデックスクエリ。この図はまた、2%と60%の間で変動します。
あなたはヒントを使用することができます。この時間は、({「ナチュラル$」:真})全表スキャンを行くためのクエリを強制します。