クエリ パフォーマンスの最適化
項目一覧
クエリをサポートするインデックスの作成
よく発行されるクエリの場合は、インデックスを作成します。クエリが複数のフィールドを検索する場合は、複合インデックスを作成します。インデックスのスキャンはコレクションのスキャンよりもはるかに高速です。インデックス構造はドキュメント参照よりも小さく、参照を順番に格納します。
例
ブログ記事を含む posts
コレクションがあり、author_name
フィールドでソートするクエリを定期的に発行する場合は、author_name
フィールドにインデックスを作成することでクエリを最適化できます。
db.posts.createIndex( { author_name : 1 } )
インデックスは与えられたフィールドを定期的にソートするクエリの効率も向上させます。
例
timestamp
フィールドでソートするクエリを定期的に発行する場合は、次のように timestamp
フィールドにインデックスを作成することでクエリを最適化できます。
このインデックスを作成します。
db.posts.createIndex( { timestamp : 1 } )
このクエリを最適化します。
db.posts.find().sort( { timestamp : -1 } )
MongoDB は昇順と降順の両方でインデックスを読み取ることができるため、単一キー インデックスの方向は関係ありません。
インデックスは、クエリ、更新操作、および集計パイプラインの一部のフェーズをサポートします。
BinData
型のインデックス キーは、次の場合、より効率的にインデックスに保存されます。
バイナリ サブタイプ値が 0〜7 または 128〜135 の範囲にあり、かつ
バイト配列の長さは、0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24 または 32 です。
ネットワークの需要を減らすためのクエリ結果数の制限
MongoDB カーソルは、複数のドキュメントのグループで結果を返します。必要な結果の数がわかっている場合は、limit()
メソッドを発行することでネットワーク リソースの需要を減らすことができます。
これは通常、ソート操作と組み合わせて使用されます。たとえば、posts
コレクションへのクエリから 10 件の結果のみが必要な場合は、次のコマンドを発行します。
db.posts.find().sort( { timestamp : -1 } ).limit(10)
結果の制限に関する詳細については、limit()
を参照してください
必要なデータのみを返すためのプロジェクションの使用
ドキュメントの一部のフィールドのみが必要な場合は、必要なフィールドのみを返すことでパフォーマンスを向上できます。
たとえば、 posts
コレクションへのクエリで、 timestamp
、 title
、 author
、および abstract
フィールドのみが必要な場合は、次のコマンドを発行します。
db.posts.find( {}, { timestamp : 1 , title : 1 , author : 1 , abstract : 1} ).sort( { timestamp : -1 } )
プロジェクションの使用方法の詳細については、「クエリから返されるプロジェクト フィールド」を参照してください。
特定のインデックスを選択するための $hint
の使用
ほとんどの場合、クエリオプティマイザは特定の操作に最適なインデックスを選択しますが、hint()
メソッドを使用して MongoDB に特定のインデックスを強制的に使用させることもできます。パフォーマンス テストをサポートする場合、または 1 つのフィールドもしくは複数のインデックスに含まれるフィールドを選択する必要がある一部のクエリの場合は、hint()
を使用します。
インクリメント演算子を使用したサーバーサイドでの操作の実行
MongoDB の $inc
演算子を使用して、ドキュメント内の値を増減します。演算子は、ドキュメントを選択し、クライアントで簡単な変更を加えてからドキュメント全体をサーバーに書き込む代わりに、サーバー側でフィールドの値を増加します。$inc
演算子は、2 つのアプリケーション インスタンスがドキュメントのクエリを行い、フィールドを手動でインクリメントし、ドキュメント全体を同時に保存した場合に発生する競合状態を回避するのにも役立ちます。