これについて私自身が実験を行ったところ、識別性の低いインデックス キーを最初に使用してもパフォーマンスが低下しないように思われることがわかりました。(私は、mmapとは異なる可能性があるwiretigerでmongodb 3.4を使用しています)。という新しいコレクションに 2 億 5000 万のドキュメントを挿入しましたitems
。各ドキュメントは次のようになります。
{
field1:"bob",
field2:i + "",
field3:i + ""
"field1"
は常に に等しかった"bob"
。 "field2"
に等しかったi
ので、完全に一意でした。最初に field2 を検索しましたが、2 億 5000 万のドキュメントをスキャンするのに 1 分以上かかりました。次に、次のようなインデックスを作成しました。
`db.items.createIndex({field1:1,field2:1})`
もちろん、フィールド 1 はすべてのドキュメントで "bob" であるため、インデックスは目的のドキュメントを見つける前に多数のアイテムを検索する必要があります。しかし、これは私が得た結果ではありませんでした。
インデックスの作成が完了した後、コレクションで別の検索を行いました。今回は、以下にリストした結果が得られました。"totalKeysExamined"
毎回 1であることがわかります。おそらく、ワイヤード タイガーか何かを使って、これをよりうまく行う方法を見つけたのでしょう。私は、wiredtiger が実際にインデックス プレフィックスを圧縮することを読んだので、それが関係している可能性があります。
db.items.find({field1:"bob",field2:"250888000"}).explain("executionStats")
{
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 4,
"totalKeysExamined" : 1,
"totalDocsExamined" : 1,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 2,
"advanced" : 1,
...
"docsExamined" : 1,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
...
"indexName" : "field1_1_field2_1",
"isMultiKey" : false,
...
"indexBounds" : {
"field1" : [
"[\"bob\", \"bob\"]"
],
"field2" : [
"[\"250888000\", \"250888000\"]"
]
},
"keysExamined" : 1,
"seeks" : 1
}
}
field3
次に、 (フィールド 2 と同じ値を持つ) にインデックスを作成しました。それから私は検索しました:
db.items.find({field3:"250888000"});
複合インデックスの場合と同じ 4ms かかりました。field2 と field3 の値を変えてこれを何度も繰り返しましたが、毎回わずかな違いしかありませんでした。これは、wiretiger を使用すると、インデックスの最初のフィールドの微分が不十分であってもパフォーマンスが低下しないことを示唆しています。