問合せ計画の概要
内部的には、問合せ実行計画は、計画イテレータのツリーとして構成されています。
各種のイテレータにより、問合せに含まれている様々な種類の式が評価されます。一般に、索引の選択や関連する索引条件の種類は、問合せのパフォーマンスに大きく影響する可能性があります。そのため開発者は、多くの場合、問合せで使用されている索引、およびそれにプッシュ・ダウンされている条件を確認する必要があります。この情報によっては、索引ヒントを介して異なる索引を強制的に使用する必要があります。この情報は、問合せ実行計画に含まれています。すべてのOracle NoSQLドライバで、問合せの実行計画を表示するAPIが提供されています。IntelliJ、VSCodeおよびEclipseプラグインなどのすべてのOracle NoSQLグラフィカルUIとOracle Cloud Infrastructureコンソールには、問合せ実行計画を表示するためのコントロールが含まれています。
問合せ実行計画内のイテレータ
問合せにおいて使用される最も一般的で重要なイテレータをいくつか次に示します。
TABLEイテレータ
- 問合せで使用される索引のスキャン(主索引の場合もある)。
- 索引にプッシュされたフィルタリング条件の適用。
- 必要に応じた、条件を満たす索引エントリで示された行の取得。索引がカバーである場合、TABLEイテレータの結果セットは索引エントリのセットであり、それ以外の場合は表の行のセットです。
ノート:
索引は、その索引のエントリのみを使用して問合せを評価できる場合、つまり、関連付けられた行を取得する必要がない場合、問合せに関するカバー索引と呼ばれます。- target table: 問合せにおけるターゲット表の名前。
- index used: 問合せで使用される索引の名前。主索引が使用されていた場合は、このプロパティの値としてprimary indexと表示されます。
- covering index: 索引がカバーであるかどうか。
- row variable: 表内の、TABLEイテレータで生成されたすべての行を対象とする、変数の名前。索引がカバーである場合は、表の行が生成されないため、この変数は使用されません。
- index scans: 実行する索引スキャンを定義する、開始条件と停止条件が含まれています。
- index row variable: TABLEイテレータで生成されたすべての索引エントリを対象とする、変数の名前。索引スキャンによって新しい索引エントリが生成されるたびに、この索引変数がそのエントリにバインドされます。
- index filtering predicate: 索引スキャンによって生成されるすべての索引エントリに対して評価する条件。この評価の結果がtrueである場合は、索引変数がこのエントリにバインドされ、TABLEイテレータでのnext()コールの結果として、そのエントリまたはそれに関連する表の行が返されます。それ以外の場合は、そのエントリがスキップされ、索引スキャンでの次のエントリが生成され、このエントリに対してその条件が再び評価され、それが、条件を満たすエントリが見つかるまで続けられます。
SELECTイテレータ
これにより、SELECT式が実行されます。
RECEIVEイテレータ
- RECEIVEイテレータ自体、およびイテレータ・ツリー内でその上にあるすべてのイテレータが、ドライバで実行されます。
- RECEIVEイテレータの下にあるすべてのイテレータは、レプリケーション・ノード(RN)で実行されます。これらのイテレータで、RECEIVEイテレータの固有の子がルートとなるサブツリーが形成されます。
一般に、RECEIVEイテレータは問合せコーディネータとして機能します。これにより、そのサブプランを適切なRNに送信して実行し、その結果を収集します。これにより、ソートや重複削除などのその他の操作を実行し、さらに処理するためにその結果を祖先イテレータ(存在する場合)に伝播することもできます。
分散の種類:
分散の種類(distribution kind)により、問合せをOracle NoSQLデータベース(ストア)に関与するすべてのRNにわたって実行するための、その問合せの分散方法を指定します。distribution kindは、RECEIVEイテレータのプロパティです。
- SINGLE_PARTITION: SINGLE_PARTITION問合せでは、そのWHERE句で、完全なシャード・キーを指定します。それにより、単一のパーティションにその完全な結果セットが含まれ、RECEIVEイテレータによって、そのパーティションが格納されている単一のRNにそのサブプランが送信されます。SINGLE_PARTITION問合せでは、主キー索引または2次索引のどちらかを使用できます。
- ALL_PARTITIONS: ここでは問合せで主キー索引が使用され、完全なシャード・キーは指定されません。その結果、ストアにM個のパーティションがある場合は、RECEIVEイテレータによって、そのサブプランのM個のコピーが送信されて、それぞれが、M個のパーティションのいずれかに対して実行されます。ストア内のパーティションの数を特定するには、show topologyを参照してください。
- ALL_SHARDS: ここでは問合せで2次索引が使用され、完全なシャード・キーは指定されません。その結果、ストアにN個のシャードがある場合は、RECEIVEイテレータによって、そのサブプランのN個のコピーが送信されて、それぞれが、N個のシャードのいずれかに対して実行されます。
問合せ実行計画の構造:
問合せ実行は、複数のバッチに分けて行われます。問合せサブプランは、実行のためにパーティションまたはシャードに送信されると、バッチ制限に到達するまでそこで実行されます。オンプレミスのNoSQLデータベースの場合、バッチ制限は、基礎となるパーティションまたはシャードから生成されるローカル結果の数です。デフォルトは結果100個ですが、それは、問合せレベルのオプションを使用して変更できます。NoSQL Database Cloud Serviceの場合、バッチ制限は、問合せによってローカルで使用される読取りユニットの数です。デフォルトは読取りユニット2000個(約2MBのデータ)であり、それは、問合せレベルのオプションによってのみ減らすことができます。
バッチ制限に到達すると、生成されたローカル結果は、まだ他にローカル結果が存在するかどうかを示すブール・フラグとともに、さらに処理するためにRECEIVEイテレータに対して送り返されます。このフラグがtrueの場合、この応答には再開情報が含まれています。RECEIVEイテレータによって、問合せを同じパーティションまたはシャードに再送信することが決定された場合は、そのリクエストにこの再開情報が含まれます。それにより、問合せ実行は、前回のバッチでの停止箇所から再開されます。これは、バッチの完了後にそのRNで問合せ状態が保持されていないためです。同じパーティションまたはシャードに対する次回のバッチは、前回のバッチと同じRNで、または同じパーティションまたはシャードが格納されている別のRNで実行できます。