1.しかし、「a」と「b」にジョイントインデックスを作成すると、単純なインデックスとどのように違いますか?
MongoDBは、クエリごとに1つのインデックスのみを使用します。したがって、find()
条件に値a
とb
値の両方が含まれている場合は、複合インデックスを追加して、両方のフィールドを効率的に検索する必要があります。
2.そして、なぜ私たちは「a」を見つけるだけで利益を得るのに、「b」を見つけた場合、それから利益を得ることができないのですか?ジョイントインデックスが「a」と「b」を連結するのと同じように、プレフィックスのメリットを得ることができるかどうか?</ p>
MongoDBはBツリーインデックスを使用するため、プレフィックスを使用して部分的なキーのみを効率的に照合できます。サフィックスまたはサブストリングに一致する可能性のあるすべての値を見つけるには、すべてのインデックスエントリをチェックする必要があります。
比較するテストデータを設定する
以下の例はmongo
シェルを使用しています。
/* Generate some test data */
for (i = 0; i< 1000; i++) {
db.mycoll.insert({a:i})
db.mycoll.insert({b:i})
db.mycoll.insert({a:i,b:i})
}
次に、いくつかのサンプルインデックスを追加します。
/* Add simple and compound index */
db.mycoll.ensureIndex({a:1})
db.mycoll.ensureIndex({b:1})
db.mycoll.ensureIndex({a:1, b:1})
最後に、以下のテストシナリオでは、クエリで特定のインデックスを使用して結果$hint
を比較するように強制しますexplain()
。
b
単純なインデックスを使用して検索
b
で単純なインデックスを使用して検索b
すると、インデックス内で直接一致するエントリを見つけることができます。4つのインデックスエントリ()をスキャンして、nscanned
4つの結果()を返しn
ます。
db.mycoll.find({b:10}).hint({b:1}).explain()
{
"cursor" : "BtreeCursor b_1",
"n" : 4,
"nscannedObjects" : 4,
"nscanned" : 4,
...
}
b
複合インデックスを使用して検索(a,b)
b
複合インデックスを使用するための検索では、インデックスの最初の部分がのキー値であるため、インデックス内の(a,b)
すべての値をチェックする必要があります。a
a
したがって、インデックス内で直接一致するエントリを見つけるには、1904個のインデックスエントリ( )をスキャンして4つの結果( )nscanned
を返します。n
db.mycoll.find({b:10}).hint({a:1,b:1}).explain()
{
"cursor" : "BtreeCursor a_1_b_1",
"n" : 4,
"nscannedObjects" : 4,
"nscanned" : 1904,
...
}
技術的に1,904のドキュメントをスキャンすることは、私のテストコレクションの合計3,000未満ですが、これは最適とはほど遠いものです。
a
複合インデックスを使用して検索(a,b)
比較のためにa
、複合インデックスを使用して検索すると、4つのドキュメントを返すためにスキャンする必要があるのは4つの値だけであることがわかります。
db.mycoll.find({a:10}).hint({a:1,b:1}).explain()
{
"cursor" : "BtreeCursor a_1_b_1",
"n" : 4,
"nscannedObjects" : 4,
"nscanned" : 4,
"nscannedObjectsAllPlans" : 4,
...
}
その他の例と説明については、 MongoDB複合インデックスの最適化の記事を読むことをお勧めします。