最近、複数のアップサートの実行( 一括操作 )と挿入(複数のドキュメント)のパフォーマンスの大きな違いに気付きました。私はこれに正しくなっているかどうかを知りたい:
find()
およびupdate()
のようになるため、読み取りと書き込みの2つのことを行いますしたがって、パフォーマンスの違いは?
この場合、ドキュメントを更新する代わりに、createdOn
フィールドを使用して新しいドキュメントを作成するために、定期的に大量の書き込みが必要かどうか疑問に思います。次に、クエリを実行するには、createdOn DESC
でソートされたドキュメントをクエリします。これは良い方法でしょうか?または、より良い方法はありますか?
ドキュメントを挿入する場合、Mongodbは同じobjectIdを持つドキュメントが存在するかどうかを確認する必要があります。そのドキュメントが存在する場合は挿入できません。
同じケースがアップデートに適用されます。ドキュメントが存在するかどうかを確認する必要があります。そうでない場合、更新を実行できません。 ObjectId/Indexedフィールドに基づいてドキュメントが見つからない場合、更新クエリが遅くなるケース。
その他のドキュメントの挿入/更新のパフォーマンスは同じである必要があります。
例えば.....
したがって、Insertは次のようになります//(Fast)
そしてupsertで更新(ObjectIdが利用可能)//(高速)
またはupsert(ObjectIdなし)//これは遅い
MongoDBでupsert
がどのように機能するかについての「公式」説明は見つかりませんでしたが、操作は既存のドキュメントの更新を目的としており、ドキュメントが指定された基準が見つかりません。
インデックスを追加すると、upsert
が高速になります。すべてのインデックスを使用してドキュメントを「検索」した後です。警告は、インデックスが動作するフィールドと更新するフィールドにあります。更新された部分がインデックスの一部である場合、ドキュメントの更新にパフォーマンスの影響があります。更新された部分がインデックスの一部ではない場合、既存のドキュメントへの書き込みに対してペナルティは発生しません。ただし、ドキュメントが追加されると、インデックスコレクションが更新されるため、パフォーマンスにわずかな影響があります。それでも、ドキュメントを追加するだけで高速になります。
したがって、シナリオでドキュメントを更新したくないことがわかっている場合、挿入は一般的に高速です。同じドキュメントを2回追加しないようにする場合は、一意のインデックスを追加することもできます。その後、挿入は失敗します。
全体的には特定のシナリオに依存しますが、質問から抽出できる情報に基づいて、ドキュメントを単に挿入することが最良の選択肢だと思います。 「createdon」フィールドを使用すると、シナリオ内でドキュメントが一意になるようにするので、読み取りシナリオで使用されるインデックスのみを考慮する必要があります。
MongoDB サイトでいくつかの追加情報を見つけることができます:
(読み取り)インデックスの設計の詳細については、インデックスがクエリプランに何かを追加するかどうかを確認するためのかなり良い説明があります here :
これがお役に立てば幸いです。