単純な標準クエリ(limit()
なし)が与えられます またはsort()
(name
のように)2つのフィールドにフィルター条件がある およびage
あなたの例では)、結果のドキュメントを見つけるために、MongoDBは次のいずれかを行います:
- 完全なコレクションスキャンを実行します (コレクション全体のすべてのドキュメントを読み取り、BSONを解析し、問題の値を見つけて、入力に対してテストし、各ドキュメントを返す/破棄します):これは非常にI / Oが集中しているため、低速です。
- 1つのインデックスを使用 フィールドの1つを保持します(インデックスツリーを使用してドキュメントの関連するサブセットを見つけ、その後スキャンします):データの分散/インデックスの選択性に応じて、これは非常に高速であるか、ほとんどメリットがありません(
age
30年から40年の間の何百万人もの人々のデータセットでは、すべての検索で無限の数のドキュメントが生成されます。 - 2つのインデックスを使用 問題の両方のフィールドが一緒に含まれています(両方のインデックスをロードし、キールックアップを実行してから、結果の共通部分を計算します):繰り返しますが、データ分布によっては、パフォーマンスが向上する場合と得られない場合があります。ただし、ほとんどの場合、#2よりも高速である必要があります。ただし、(おっしゃるように)#4よりも実際に10倍遅いとしたら驚きます。
- 複合インデックスを使用する (2つの後続のキールックアップはすぐに必要なドキュメントにつながります):これは、適切なドキュメントに到達するために必要な操作が最小で最も安価であることを考えると、すべての中で最速のオプションになります。最高レベルの再利用(これによって影響を受けないパフォーマンスではない)を保証するには、通常、最も選択的なフィールドから始める必要があります。したがって、あなたの場合はおそらく
name
age
ではありません 多くの人が同じage
を持っていることを考えると (選択性が非常に低い)name
と比較して (より高い選択性)。ただし、その選択は、具体的なシナリオと、データベースに対して実行する予定のクエリによっても異なります。特定の状況のさまざまな側面を考慮に入れて複合インデックスを最適に定義する方法については、Web上にかなり良い記事があります:https://emptysqua.re/blog/optimizing-mongodb-compound-indexes
考慮すべき他の側面は次のとおりです。インデックスの更新は特定の価格で提供されます。ただし、気になるのが生の読み取り速度だけであり、更新が数回しかない場合は、より多くの/より大きなインデックスを選択する必要があります。
そして最後になりましたが(!)よく使われている最終的なアドバイス:実際のデータとおそらく現実的な負荷シナリオを使用して、システムから地獄をプロファイリングします。また、データ/システムが時間の経過とともに変化するにつれて測定を続けます。
追加の読み取り:https://docs.mongodb.com/manual/core/query-optimization/index.html
https://dba.stackexchange.com/questions/158240/mongodb-index-intersection-does-not-eliminate-the-need-for-creating-compound-in
インデックスの共通部分と複合インデックス?
mongodbcompundインデックスとインデックス交差
複合インデックスの順序は、MongoDBのパフォーマンス面でどのように重要ですか?
MongoDBでは、大規模なクエリを使用しており、複合インデックスまたは単一インデックスを作成する方法を使用しているため、応答時間が向上します