このページでは、Query Explain で実行されたクエリの出力について説明します。Query Explain でクエリを実行する方法については、Query Explain でクエリの実行を分析するをご覧ください。
共通のコンセプト
実行ツリー全体で、次の一般的なコンセプトと用語が使用されます。
行とレコード
「行」と「レコード」という用語は、ドキュメントまたはインデックス エントリを一般的に指すために使用されます。
変数
$
は、実行ツリーで作成または参照される変数を示します。例: $foo_1
。これらの変数は通常、ドキュメントの内容や、クエリの実行中に評価された式の値を参照するために使用されます。
実行ノードには、次の内部変数を使用できます。
$__key__
- キーはドキュメントの内部識別子です。これは、プロジェクト、データベース、ドキュメントの完全なパスを含む絶対一意の識別子です。$__id__
- ID は、コレクション内のドキュメントの一意の識別子です。これは、単一のコレクション内で一意です。
Compute
ノードを使用してドキュメント __key__
から __id__
を計算する例を考えてみましょう。
Compute
| $__id__1: _id($__key__)
| records returned: 1
制約と範囲
一部のスキャンノードは、constraints
属性と ranges
属性を使用して、スキャンされる値の範囲を記述します。これらの属性は、値のリストを含む範囲ツリー形式を使用します。これらの値は、インデックス定義に表示されるキーの順序付きリストに対応しています。たとえば、ツリーに最初に表示される範囲(ここでは (1..5]
)は、キーの順序付きリストの最初のキー(ここでは a
)の制約に対応します。
| index: type=CollectionGroupIndex, id=CICAgOjXh#EK, keys=[a ASC, b ASC, __key__ ASC]
| constraints: /
|----(1..5]
|----[1L]
インデントの各レベルは、リスト内の次のキーに適用される制約を示します。角かっこは範囲の境界を含み、丸かっこは範囲の境界を含まない。この場合、制約は 1 < "a" <= 5
と "b" = 1
に変換されます。
次の例では、a
の複数のブランチがあり、制約は 1 < a <= 5 OR a = 10
に対応しています。
| constraints: /
|----(1L, 5L]
|----[10L]
キー変数
一部のスキャンノード(SequentialScan
など)では、index
属性の一部としてキーのリストがあり、Scan
ノードに個別の keys
属性があります。Scan
ノードの keys
属性は、インデックス定義の各キーの変数名を順に示します。これらの変数を使用すると、実行ツリーの上位にあるスキャンされたフィールドのランタイム値を参照できます。
次の例では、現在のドキュメントの user
フィールドの値が変数 $user_1
にマッピングされ、date_placed
の値が $date_placed_1
にマッピングされます。
index: type=CollectionGroupIndex, id=CICAgOjXh4EK, keys=[user ASC, date_placed ASC, __key__ ASC]
keys: [user ASC, date_placed ASC, __key__ ASC]
実行ノード
クエリ実行ツリーには、次のノードを含めることができます。
SeekingScan
返される行がインデックスの単一の連続範囲に沿っていない可能性があり、クエリを満たすために複数の個別のスキャンを実行する必要がある動的スキャンを表します。
たとえば、a
が存在し、b
が 1 に等しいクエリが ["a" ASC, "b" ASC]
のインデックスで動作する場合、a
の個別の値ごとに、別個の(順序どおりでない可能性のある)範囲をスキャンして返す必要があります。これは完全な TableScan
よりも効率的ですが、["b" ASC, "a" ASC]
の複合インデックスに対する単一の SequentialScan
よりも効率が低くなります。
• SeekingScan
| constraints: /
|----(-∞..+∞)
|----[1L]
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, quantity ASC, __key__ ASC]
| keys: [user ASC, quantity ASC, __key__ ASC]
| properties: Selection { user }
| records returned: 1
| records scanned: 1
SequentialScan
1 回の読み取りオペレーションで実行できる、ストレージ内の静的で連続した行の範囲のスキャンを表します。
key ordering length
は、元のキーの順序で保持して返す必要があるキーの数を指します。[k1, k2, k3]
のスキーマの場合、キー順序の長さが 0 の場合、スキャンは任意の順序で返すことができます。1 の場合、k1 で順序付けされますが、同じ k1 値を持つ行は任意の順序で取得できます。3 の場合、ドキュメントは正確なソート順で返されます。
• SequentialScan
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| key ordering length: 3
| keys: [user ASC, date_placed ASC, __key__ ASC]
| limit: 10
| properties: Selection { a }
| ranges: /
| records returned: 1
| records scanned: 1
UniqueScan
ストレージ内の静的で連続した行の範囲のスキャンを表します。行のメモリ内重複除去が行われます。
• UniqueScan
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| keys: [user ASC, date_placed ASC, __key__ ASC]
| properties: Selection { a }
| ranges: /
|----(-∞..+∞)
| records returned: 1
| records scanned: 1
TableAccess
指定された行の識別子を、プライマリ ストレージの実際の行の内容にバックジョインします。親ノード(または最終的なクエリ結果)でドキュメントのフィールドのサブセットが必要な場合は、TableAccess
が必要です。
• TableAccess
| order: PRESERVE_INPUT_ORDER
| peak memory usage: 4.00 KiB (4,096 B)
| properties: *
| records returned: 1
LookupById
ID で外部コレクションのドキュメントを検索して結合を実行します。ルックアップする ID は、入力ドキュメントのフィールドから取得されます。ルックアップの結果は、入力ドキュメントに新しいフィールドとして追加されます。
• LookupById
| local_field: $localField_1
| foreign_datasource: (default)#/**/foreign
| output: $output_1
TableScan
コレクションの完全な順序なしスキャン。関連付けられたインデックスなしでクエリが実行された場合に使用されます。
順序は STABLE
または UNDEFINED
のいずれかです。STABLE
は決定論的順序付けを表します。
• TableScan
| order: STABLE
| properties: *
| records returned: 1
| records scanned: 1
| source: (default)#/**/collection
HashAggregate
集計オペレーションのハッシュバック実装。結果を返す前にグループ全体をメモリにマテリアライズする必要があり、クエリのメモリ上限を超えてはなりません。
• HashAggregate
| aggregations: [sum($b_1) AS total]
| groups: [$a_1]
| peak memory usage: 4.00 KiB (4,096 B)
| records returned: 0
StreamAggregate
一度に 1 つのグループの状態のみを維持する特殊な集計ノード。ピーク時のメモリ使用量を削減します。基盤となる子ノードがグループを順番に返す場合に使用されます。たとえば、フィールドのインデックスを使用しながら、そのフィールドの個別の値でグループ化する場合などです。
• StreamAggregate
| keys: [foo ASC, bar ASC]
| properties: Selection { baz }
| aggregations: [$sum($foo_1) AS baz]
MajorSort
固定された一連のプロパティに対して並べ替えオペレーションを実行します。すべてのレコードをメモリに一度にマテリアライズし、並べ替えられた値を順番に返します。並べ替えセットのサイズはクエリのメモリ上限によって制限されます。
後続の制限が指定されている場合は、top-k ソート アルゴリズムを使用してメモリ使用量を削減します。この方法では、k 個の要素の保存に使用されるメモリが上限を超えない限り、任意のサイズのレコードセットで並べ替えを実行できます。
• MajorSort
| fields: [a ASC, b DESC]
| limit: 10
| peak memory usage: 4.00 KiB (4,096 B)
| records returned: 1
Concat
複数の子ノードの結果を連結し、結果を親ノードに返します。このノードは、複数の子に表示される結果を重複除去しません。また、返される結果の順序は非決定的です。
• Concat
├── • TableAccess
...
├── • TableAccess
コンピューティング
一連の式を評価し、結果を一連の変数に割り当てます。
• Compute
| $user_1: user
| $full_name_1: str_concat($first_name_1, " ", $last_name_1)
| $address_1: UNSET
| records returned: 1
フィルタ
指定した式に一致する場合にのみ、行を選択的に返します。
• Filter
| expression: $eq(foo, "bar")
| records returned: 1
値
処理するリテラル値のシーケンスを生成します。主に、ドキュメントのセットリストがクエリの入力として提供される場合に使用されます。
• Values
| expression: [{__key__=/col/1}, {__key__=/col/2}]
Unnest
子ノードによって生成された値のネストを解除します。
• Unnest
| expression: foo AS unnested_foo
上限
親ノードに返される行数を制限します。
• Limit
| limit: 10
| records returned: 1
オフセット
子ノードによって生成された行を、指定された数だけスキップします。
• Offset
| offset: 10
| records returned: 1