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

クエリプラン

項目一覧

  • プラン キャッシュ エントリの状態
  • queryHash
  • planCacheKey
  • 可用性

MongoDB クエリ プランナーは、どのクエリに対しても、使用可能なインデックスを考慮して最も効率的なクエリプランを選択し、キャッシュします。クエリプランの効率性を評価するために、クエリ プランナーはすべての候補プランを試用期間中に実行します。一般的に、選出されるプランは、試用期間中に実行する作業量が最も少なく、最も多くの結果が得られるクエリプランです。

関連付けられているプラン キャッシュ エントリは、同じクエリシェイプを持つ後続のクエリに使用されます。

以下の図はクエリプランナーのロジックを示しています。

MongoDB のクエリプランナー ロジックの図。
クリックして拡大します

注意

explainを使用すると、既存のすべてのプラン キャッシュ エントリが無視され、MongoDB クエリ プランナーが新しいプラン キャッシュ エントリを作成できなくなります。

各プランキャッシュのクエリシェイプは、キャッシュ内の3つの状態のうちの1つに関連付けられています。

状態
説明
欠損(Missing)

このシェイプのエントリはキャッシュに存在しません。

クエリの場合、クエリシェイプのキャッシュ エントリ状態が欠落している場合、次のようになります。

  1. 候補プランが評価され、勝者となるプランが選択されます。

  2. キャッシュは、プランに必要な作業量を定量化する値を持つ、非アクティブ状態のクエリシェイプのエントリを作成します。

The entry in the cache is a placeholder entry for this shape. つまり、プランナーは シェイプを確認し、プランに必要な作業量を定量化する値を計算し、 シェイプ プレースホルダー エントリを保存しましたが、クエリシェイプはクエリプランの生成に使用されることはありません

クエリの場合、シェイプのキャッシュ エントリ状態が非アクティブな場合、次のようになります。

  1. 候補プランが評価され、勝者となるプランが選択されます。

  2. プランに必要な作業量を定量化する選択したプランの値は、非アクティブなエントリの と比較されます。 選択したプランの 値が次の場合:

    • 非アクティブなエントリの値以下の場合

      選択したプランはプレースホルダーの非アクティブなエントリを置き換え、アクティブ状態になります。

      置換が行われる前に、非アクティブなエントリがアクティブになった場合(たとえば、別のクエリ操作のため)、新しくアクティブになったエントリは、プランに必要な作業量を定量化する値が選択したプランより大きい場合にのみ置換されます。

    • 非アクティブなエントリの より大きい場合
      非アクティブなエントリは残りますが、プランに必要な作業量を定量化する値は増加します。

キャッシュ内のエントリは勝者プランのものですプランナーはこのエントリを使用してクエリプランを生成できます。

クエリで、シェイプのキャッシュ エントリの状態がアクティブの場合、以下のようになります。

アクティブなエントリはクエリプランの生成に使用されます。

プランナーはエントリのパフォーマンスも評価し、プランに必要な作業量を定量化する値が選択基準を満たさなくなった場合は、非アクティブ状態に移行します。

プラン キャッシュの変更をトリガーする追加のシナリオについては、「プラン キャッシュのフラッシュ」を参照してください。

特定のクエリのクエリプラン情報を表示するには、 db.collection.explain() または cursor.explain() を使用します。

コレクションのプラン キャッシュ情報を表示するには、$planCacheStats 集計ステージを使用できます。

mongod が再起動またはシャットダウンした場合、クエリプランのキャッシュは保持されません。さらに、

  • インデックスやコレクションの削除などのカタログ操作により、プラン キャッシュが消去されます。

  • 最近の使用頻度が最も少ない(LRU)キャッシュを置換するメカニズムにより、状態に関係なく、最近のアクセス頻度が最も少なかったキャッシュ エントリーが消去されます。

ユーザーは次の操作も可能です。

  • PlanCache.clear() メソッドを使用してプラン キャッシュ全体を手動でクリアします。

  • PlanCache.clearPlansByQuery()メソッドを使用して、特定のプラン キャッシュのエントリを手動でクリアします。

Tip

以下も参照してください。

MongoDB 5.0以降では、すべてのコレクションのplan cachesの累積サイズが0.5より小さい場合にのみ、プラン キャッシュは完全なplan cacheエントリを保存します。 GB。 すべてのコレクションのplan cachesの累積サイズがこのしきい値を超えると、追加のplan cacheエントリが次のデバッグ情報なしで保存されます。

plan cache エントリの推定サイズ(バイト単位)は、$planCacheStats の出力に表示されます。

同じクエリ シェイプを持つ低速クエリを識別できるように、各クエリ シェイプは queryHash に関連付けられています。 queryHash は、クエリ シェイプのハッシュを表す 16 進数のstringで、クエリ シェイプのみに依存します。

注意

他のハッシュ関数と同様に、2 つの異なるクエリシェイプで同じハッシュ値が生成される場合があります。ただし、異なるクエリシェイプ間でハッシュ衝突が発生する可能性は低くなります。

クエリプラン キャッシュに関する詳細なインサイトを提供するために、MongoDB ではplanCacheKeyが提供されています。

planCacheKey は、クエリに関連付けられたプラン キャッシュ エントリのキーのハッシュです。

注意

queryHash と違って planCacheKey は、クエリシェイプとそのシェイプで現在使用可能なインデックスの両方の関数です。つまり、クエリシェイプのサポートが可能なインデックスが追加または削除された場合、planCacheKey 値は変わる可能性がありますが、queryHash の値は変化しません。

たとえば、次のインデックスを持つコレクション foo を考えます。

db.foo.createIndex( { x: 1 } )
db.foo.createIndex( { x: 1, y: 1 } )
db.foo.createIndex( { x: 1, z: 1 }, { partialFilterExpression: { x: { $gt: 10 } } } )

このコレクションに対する次のクエリは、同じシェイプです。

db.foo.explain().find( { x: { $gt: 5 } } ) // Query Operation 1
db.foo.explain().find( { x: { $gt: 20 } } ) // Query Operation 2

このようなクエリがある場合、部分フィルター式を含むインデックスはクエリ操作 2 をサポートできますが、クエリ操作 1 はサポートしません。クエリ操作 1 をサポートするために使用できるインデックスはクエリ操作 2 とは異なるため、2 つのクエリの planCacheKey は異なります。

いずれかのインデックスが削除された場合、または新しいインデックス { x: 1, a: 1 } が追加された場合、両方のクエリ操作の planCacheKey が変更されます。

queryHashplanCacheKey は以下で利用可能です。

インデックス フィルターはplanCacheSetFilterコマンドで設定され、クエリシェイプについてどのインデックスがオプティマイザに評価されるかを決定します。 クエリシェイプは、クエリ、並べ替え、およびプロジェクションの仕様の組み合わせで構成されます。 特定のクエリシェイプに インデックス フィルター が存在する場合、オプティマイザはフィルターで指定されたインデックスのみを考慮します。

クエリシェイプについてのインデックス フィルターが存在する場合、MongoDB は hint() を無視します。MongoDB がクエリシェイプにインデックス フィルターを適用したかどうかを確認するには、db.collection.explain() メソッドまたは cursor.explain() メソッドの indexFilterSet フィールドを確認します。

インデックス フィルターは、オプティマイザが評価するインデックスのみに関係します。オプティマイザは、特定のクエリシェイプの最適なプランとしてコレクションスキャンを選択する場合でも、コレクションスキャンを選択する場合があります。

インデックス フィルターは、サーバープロセスの実行中のみ存在し、シャットダウン後は保持されません。MongoDB には、フィルターを手動で削除するコマンドも用意されています。

インデックス フィルターはhint()メソッドと同様に、オプティマイザーに期待される動作をオーバーライドするため、インデックス フィルターの使用は控えめにしてください。

MongoDB 6.0 以降、インデックス フィルターは、以前はplanCacheSetFilter コマンドを使用して設定されていた照合を使用します。

戻る

書込みパフォーマンス