Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Docs Menu
Docs Home
/
データベース マニュアル
/ /

クエリの最適化

クエリの最適化は、クエリ操作で加工する必要があるデータ量を減らすことで、読み取り操作の効率を向上させます。インデックス、プロジェクション、クエリ制限を使用して、クエリのパフォーマンスを向上させ、リソース消費を削減します。

よく実行されるクエリにインデックスを作成します。クエリが複数のフィールドを検索する場合は、複合インデックスを作成します。インデックスを使用するとパフォーマンスが向上します。これは、インデックスがない場合、クエリはコレクション内のすべてのドキュメントをスキャンする必要があるためです。

例、inventoryコレクションの typeフィールドに対する次のクエリを考えてみましょう。

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

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

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

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

[1] 単一フィールド インデックスの場合、インデックスの順序は重要ではありません。複合インデックスの場合、フィールドの順序はインデックスがサポートするクエリに影響します。詳細については、ソート順序を参照してください。

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

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

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

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

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

ドキュメントの一部のフィールドセットが必要な場合は、必要なフィールドのみを返すことでパフォーマンスを向上できます。プロジェクションにより、ネットワーク トラフィックと処理時間が削減されます。

例、postsコレクションへのクエリに timestamptitleauthorabstract フィールドのみが必要な場合は、プロジェクションでそれらのフィールドを指定します。

db.posts.find(
{},
{ timestamp : 1, title : 1, author : 1, abstract : 1}
).sort( { timestamp : -1 } )

$project集計ステージを使用する場合、それは通常パイプラインの 最後のステージ であり、クライアントに返すフィールドを指定するために使用されます。

$project ステージをパイプラインの開始または中間で使用して、後続のパイプラインステージに渡されるフィールドの数を減らしてもパフォーマンスが改善する可能性はほとんどありません。データベースではこの最適化が自動的に実行されているためです。

プロジェクションの使用方法の詳細については、「クエリから返されるプロジェクト フィールド」を参照してください。

MongoDB カーソル は結果をバッチで返します。必要な結果の数がわかっている場合は、limit() メソッドでその値を指定します。結果を制限すると、ネットワーク リソースの需要が減ります。

一般的に、結果を制限すると、結果がソートされ、どのドキュメントが返されるかがわかっている場合に最も便利です。例、postsコレクションへのクエリから 10 の結果のみが必要な場合は、次のクエリを実行します。

db.posts.find().sort( { timestamp : -1 } ).limit(10)

結果の制限の詳細については、limit() を参照してください。

クエリオプティマイザは通常、特定の操作に最適なインデックスを選択します。ただし、hint() メソッドを使用してMongoDBに特定のインデックスを強制的に使用させることもできます。hint()パフォーマンス テストをサポートする場合、または複数のインデックスに表示されるフィールドをクエリしてMongoDB が正しいインデックスを使用していることを保証する場合は、を使用します。

MongoDB の $inc 演算子を使用して、ドキュメント内の値を増減します。演算子は、ドキュメントを選択し、クライアントで簡単な変更を加え、その後ドキュメント全体をサーバーに書き込む の代わりに、サーバー側でフィールドの値を増加します。$inc 演算子は、2 つのアプリケーションインスタンスがドキュメントをクエリし、フィールドを手動で増加させて、ドキュメント全体を同時に保存するときに発生する競合状態を回避するのにも役立ちます。

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

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

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

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

    • { "field": null }

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

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

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

このインデックスでは、type フィールドと item フィールドをクエリし、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() メソッドを使用します。「カバード クエリ」を参照してください。

戻る

因果整合性

ルール バッジを取得する

「クエリの最適化」を無料でマスターしましょう!

詳細

項目一覧