Docs Menu
Docs Home
/
MongoDBマニュアル
/ /

クエリの最適化

項目一覧

  • 読み取り操作をサポートするインデックスの作成
  • クエリの選択性
  • カバード クエリ
  • 埋め込みドキュメント
  • マルチキーのカバーリング
  • パフォーマンス
  • 制限
  • explain

インデックスは、クエリ操作で加工する必要があるデータ量を減らすことで、読み取り操作の効率を向上させます。これにより、MongoDB 内でクエリを実行する作業が簡素化されます。

アプリケーションが特定のフィールドまたはフィールド セットのコレクションをクエリする場合、クエリされたフィールドのインデックスまたはフィールド セットの複合インデックスにより、クエリがコレクション全体をスキャンしてクエリ結果を検索して返すことを防ぐことができます。 インデックスの詳細については、「 MongoDB のインデックスに関する完全ドキュメント 」を参照してください

アプリケーションは、type フィールドの inventory コレクションをクエリします。type フィールドの値はユーザー ドリブンです。

var typeValue = <someUserInput>;
db.inventory.find( { type: typeValue } );

このクエリのパフォーマンスを向上させるには、 typeフィールドのinventoryコレクションに昇順または降順のインデックスを追加します。 [ 1 ] mongoshでは、 db.collection.createIndex()メソッドを使用してインデックスを作成できます。

db.inventory.createIndex( { type: 1 } )

このインデックスにより、上記の type のクエリがコレクション全体をスキャンして結果を返すのを防ぐことができます。

インデックスを使用してクエリのパフォーマンスを分析するには、「クエリ パフォーマンスの分析 」を参照してください。

読み取り操作の最適化に加えて、インデックスはソート操作をサポートし、より効率的なストレージ利用を可能にします。インデックス作成の詳細については、db.collection.createIndex() および「インデックス」を参照してください。

[1] 単一フィールド インデックスの場合、昇順か降順かの選択は重要ではありません。複合インデックスの場合、この選択は重要です。詳細については、「インデックス順序」を参照してください。

クエリの選択性とは、クエリ述語がコレクション内のドキュメントをどの程度適切に除外またはフィルタリングするかを指します。クエリの選択性によって、クエリがインデックスを効果的に使用できるかどうか、あるいはインデックスをまったく使用しないかが決まります。

選択性の高いクエリほど、一致するドキュメントの割合は少なくなります。たとえば、ユニークな _id フィールドでの等価一致は、多くとも 1 件のドキュメントにしか一致しないため、選択性が非常に高くなります。

選択性の低いクエリは、一致するドキュメントの割合は多くなります。選択性の低いクエリは、インデックスを効果的に使用できない、あるいはまったく使用できません。

たとえば、不等式演算子 $nin$ne は、インデックスの大部分と一致することが多いため、あまり選択的ではありません。その結果、多くの場合、インデックス付きの $nin クエリまたは $ne クエリのパフォーマンスは、コレクション内のすべてのドキュメントをスキャンする必要がある $nin クエリまたは $ne クエリのパフォーマンスと同程度になる可能性があります。

regular expressions の選択性は式自体に依存します。詳細については、「正規表現とインデックスの使用」をご覧ください。

カバード クエリとは、インデックスを使用して処理が完了し、ドキュメントを調査する必要がないクエリです。次のすべてが当てはまる場合、インデックスはクエリをカバーします。

  • クエリ内のすべてのフィールド(アプリケーションで指定されたフィールドと、シャーディングなどの内部で必要なフィールドの両方)はインデックスの一部です。

  • 結果に返されるすべてのフィールドは同じインデックスにある

  • クエリ内のどのフィールドも null に等しくありません。例、次のクエリ述語ではカバード クエリは作成されません。

    • { "field": null }

    • { "field": { $eq: null } }

inventoryコレクションでは、type フィールドと item フィールドには次のインデックスがあります。

db.inventory.createIndex( { type: 1, item: 1 } )

このインデックスは、typeitem フィールドにクエリをかけ、item フィールドのみを返す、以下の操作に対応しています:

db.inventory.find(
{ type: "food", item:/^c/ },
{ item: 1, _id: 0 }
)

指定されたインデックスがクエリをカバーするには、インデックスに _id フィールドが含まれていないため、プロジェクション ドキュメントは _id: 0 を明示的に指定して結果から _id フィールドを除外する必要があります。

インデックスは、埋め込みドキュメント内のフィールドに対するクエリをカバーできます。

例、次の形式のドキュメントを含む userdataコレクションを考えてみましょう。

db.userdata.insertOne(
{ _id: 1, user: { login: "tester" } }
)

コレクションには、次のインデックスがあります。

db.userdata.createIndex(
{ "user.login": 1 }
)

{ "user.login": 1 }インデックスは、次のクエリを対象としています。

db.userdata.find(
{ "user.login": "tester" },
{ "user.login": 1, _id: 0 }
)

注意

埋め込みドキュメントのフィールドにインデックスを付けるには、ドット表記を使用します。埋め込みフィールドでの索引の作成を参照してください。

マルチキー インデックスは、どのフィールドがインデックスをマルチキーにするかを追跡する場合、非配列フィールドに対するクエリをカバーできます。

マルチキー インデックスは、配列フィールドに対する カバー クエリは実行できません。

マルチキー・インデックスを使用したカバード・クエリの例については、マルチキー・インデックスのページのカバード・クエリを参照してください。

インデックスにはクエリに必要なすべてのフィールドが含まれているため、MongoDB はクエリ条件を一致させることも、インデックスのみを使用して結果を返すこともできます。

インデックスのみをクエリする方が、インデックス外のドキュメントをクエリするよりもはるかに高速です。インデックス キーは通常、カタログするドキュメントよりも小さく、インデックスは通常 RAM で利用可能か、ディスク上に連続してに配置されます。

すべてのインデックスタイプがクエリをカバーできるわけではありません。対象インデックスのサポートの詳細については、対応するインデックスタイプのドキュメントページを参照してください。

mongos で実行すると、インデックスにシャードキーが含まれている場合にのみ、シャーディングされたコレクションのクエリをカバーできます。

クエリがカバーされたクエリであるかどうかを判断するには、 db.collection.explain()メソッドまたはexplain()メソッドを使用します。 「 カバード クエリ 」を参照してください。

戻る

因果整合性