クエリのパフォーマンスの最適化
実行速度が遅いクエリのトラブルシューティングを行うには、クエリ Explain を使用して、クエリ実行プランとランタイム実行プロファイルを取得します。以降のセクションでは、実行プロファイルに応じてクエリのパフォーマンスを最適化するために実行できる手順について説明します。結果の個数を制限する
実行ツリーで「records returned」フィールドを使用して、クエリが多くのドキュメントを返しているかどうかを確認します。$limit
句を使用して、返されるドキュメントの数を制限することを検討してください。これにより、ネットワーク経由でクライアントに返される結果のシリアル化バイトサイズが削減されます。Limit
ノードの前に MajorSort
ノードがある場合、クエリエンジンは Limit
ノードと MajorSort
ノードを統合し、完全なインメモリ マテリアライゼーションと並べ替えを TopN 並べ替えに置き換えて、クエリのメモリ要件を削減できます。
結果ドキュメントのサイズを制限する
不要なフィールドの取得を回避するために、$project
句を使用して返されるドキュメントのサイズを制限することを検討してください。これにより、中間結果の処理にかかるコンピューティングとメモリのコストと、ネットワーク経由でクライアントに返される結果のシリアル化されたバイトサイズを削減できます。クエリで参照されるすべてのフィールドが通常のインデックス(マルチキーではない)でカバーされている場合、クエリをインデックス スキャンで完全にカバーできるため、プライマリ ストレージからドキュメントを取得する必要がなくなります。
インデックスを使用する
次の手順でインデックスを設定して最適化します。
クエリでインデックスが使用されているかどうかを確認する
クエリがインデックスを使用しているかどうかは、実行ツリーのリーフノードを確認することで確認できます。実行ツリーのリーフノードが TableScan ノードである場合、クエリはインデックスを使用しておらず、プライマリ ストレージからドキュメントをスキャンしています。インデックスが使用されている場合、実行ツリーのリーフノードには、インデックスの ID とインデックス フィールドが表示されます。
使用しているインデックスを最適化できるかどうかを確認する
インデックスは、クエリエンジンがプライマリ ストレージから取得する必要があるドキュメントの数を減らせる場合や、フィールドの順序付けによってクエリの並べ替え要件を満たせる場合に、クエリに役立ちます。
クエリにインデックスが使用されているにもかかわらず、クエリエンジンが多くのドキュメントをフェッチして破棄している場合(多くのレコードを返す Scan ノードと、少数のレコードを返す Filter ノードが続く)、インデックスを使用して満たされるクエリ述語が選択的ではないことを示しています。より適切なインデックスを作成するには、インデックスを作成するをご覧ください。
クエリにマルチキー以外のインデックスが使用されているにもかかわらず、クエリ実行ツリー内の MajorSort ノードで識別されるように、クエリエンジンが結果セットのインメモリ並べ替えを実行している場合、使用されているインデックスを使用してクエリの並べ替え要件を満たすことができない可能性があります。より適切なインデックスを作成するには、次のセクションをご覧ください。
インデックスを作成する
インデックス管理のドキュメントに沿って、インデックスを作成します。クエリでインデックスを使用できるようにするには、次の順序でフィールドを含む通常のインデックス(マルチキーではない)を作成します。
- 等価演算子で使用されるすべてのフィールド。クエリ間での再利用の可能性を最大化するには、クエリ間で等価演算子内のフィールドの出現頻度の降順でフィールドを並べ替えます。
- 並べ替えるすべてのフィールド(同じ順序で)。
- 範囲演算子または不等式演算子で使用されるフィールド(クエリ制約の選択性の降順)。
- インデックスのクエリの一部として返されるフィールド: このようなフィールドをインデックスに含めると、インデックスでクエリをカバーできるため、プライマリ ストレージからドキュメントを取得する必要がなくなります。
配列フィールドのフィルタリングと並べ替えを含むクエリの場合は、マルチキー インデックスの作成を検討してください。
クエリヒントを使用する
クエリに適したインデックスを作成しても、クエリエンジンがそのインデックスを使用していない場合は、クエリヒントを使用してクエリエンジンのインデックス設定をオーバーライドできます。