

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# openCypher `explain` 機能
<a name="access-graph-opencypher-explain"></a>

openCypher の `explain` 機能は、Neptune エンジンが取る実行アプローチの理解に役立つ Amazon Neptune のセルフサービスツールです。explain を呼び出すには、openCypher [HTTPS](access-graph-opencypher-queries.md) リクエストに `explain={{mode}}` でパラメータを渡します。`mode` の値は次のいずれかになります。

****
+ **`static`** - `static` モードでは、`explain` はクエリプランの静的構造のみを表示します。実際にはクエリを実行しません。
+ **`dynamic`** — `dynamic` モードでは、`explain` はクエリも実行し、クエリプランの動的な要素も含まれます。これらには、演算子を介して通過する中間バインドの数、送信バインドに対する着信バインドの割合、各演算子の所要合計時間が含まれる場合があります。
+ **`details`** - `details` モードでは、`explain` は動的モードで表示される情報に加えて、実際の openCypher クエリ文字列や、結合演算子が基づくパターンの推定範囲数などの詳細を出力します。

  

例えば、 を `dynamic` モード`POST`で使用するとします。

------
#### [ AWS CLI ]

```
aws neptunedata execute-open-cypher-explain-query \
  --endpoint-url https://{{your-neptune-endpoint}}:{{port}} \
  --open-cypher-query "MATCH (n) RETURN n LIMIT 1" \
  --explain-mode dynamic
```

詳細については、 コマンドリファレンスの [execute-open-cypher-explain-query](https://docs.aws.amazon.com/cli/latest/reference/neptunedata/execute-open-cypher-explain-query.html) AWS CLI を参照してください。

------
#### [ SDK ]

```
import boto3
from botocore.config import Config

client = boto3.client(
    'neptunedata',
    endpoint_url='https://{{your-neptune-endpoint}}:{{port}}',
    config=Config(read_timeout=None, retries={'total_max_attempts': 1})
)

response = client.execute_open_cypher_explain_query(
    openCypherQuery='MATCH (n) RETURN n LIMIT 1',
    explainMode='dynamic'
)

print(response['results'].read().decode('utf-8'))
```

他の言語の AWS SDK の例については、「」を参照してください[AWS SDK](access-graph-opencypher-sdk.md)。

------
#### [ awscurl ]

```
awscurl https://{{your-neptune-endpoint}}:{{port}}/openCypher \
  --region {{us-east-1}} \
  --service neptune-db \
  -X POST \
  -d "query=MATCH (n) RETURN n LIMIT 1" \
  -d "explain=dynamic"
```

**注記**  
この例では、 AWS 認証情報が 環境で設定されていることを前提としています。{{us-east-1}} を Neptune クラスターのリージョンに置き換えます。

------
#### [ curl ]

```
curl https://{{your-neptune-endpoint}}:{{port}}/openCypher \
  -d "query=MATCH (n) RETURN n LIMIT 1" \
  -d "explain=dynamic"
```

------

## Neptune における openCypher `explain` の制限事項
<a name="access-graph-opencypher-explain-limitations"></a>

openCypher explain の現在のリリースには、次のような制約事項があります。
+ explain プランは、現在、読み取り専用操作を実行するクエリでのみ使用できます。`CREATE`、`DELETE`、`MERGE`、`SET` など、何らかのニューテーションを行うクエリはサポートされていません。
+ 特定のプランの演算子と出力は、将来のリリースで変更される可能性があります。

## openCypher `explain` 出力に含まれる DFE 演算子
<a name="access-graph-opencypher-dfe-operators"></a>

openCypher `explain` 機能が提供する情報を使用するには、[DFE クエリエンジン](neptune-dfe-engine.md)の仕組みについて、いくつかの詳細を理解する必要があります (DFE は Neptune が openCypher クエリの処理に使用するエンジン)。

DFE エンジンは、すべてのクエリを演算子のパイプラインに変換します。最初の演算子から始まり、中間ソリューションは、1 つの演算子から次の演算子へと、この演算子パイプラインを流れます。explain テーブルの各行は、評価ポイントまでの結果を表します。

DFE クエリプランで使用できる演算子は次のとおりです。

**DFEApply** — 指定した変数に保存されている値に対して、引数セクションで指定した関数を実行します。

**DFEBindRelation** — 指定された名前の変数を結合します。

**DFEChunkLocalSubQuery** — これは実行中のサブクエリのラッパーとして機能するノンブロッキング操作です。

**DFEDistinctColumn** — 指定された変数に基づいて、入力値の個別のサブセットを返します。

**DFEDistinctRelation** — 指定された変数に基づいて、入力ソリューションの個別のサブセットを返します。

**DFEDrain** — サブクエリの最後に表示され、そのサブクエリの終了ステップとして機能します。ソリューションの数は `Units In` として記録されます。`Units Out` は常に 0 です。

**DFEForwardValue** — すべての入力チャンクを出力チャンクとして直接コピーし、ダウンストリームの演算子に渡します。

**DFEGroupByHashIndex** — 以前に計算したハッシュインデックス (`DFEHashIndexBuild` 操作を使用) に基づいて、入力ソリューションに対してグループ化操作を実行します。出力として、指定された入力は、すべての入力ソリューションのグループキーを含む列によって拡張されます。

**DFEHashIndexBuild** — 副作用として一連の変数に対してハッシュインデックスを構築します。通常、このハッシュインデックスは後の操作で再利用されます。このハッシュインデックスの使用場所については、`DFEHashIndexJoin` または `DFEGroupByHashIndex` を参照してください。

**DFEHashIndexJoin** — 以前に構築したハッシュインデックスに対して受信ソリューションで結合を実行します。このハッシュインデックスの構築場所については、`DFEHashIndexBuild` を参照してください。

**DFEJoinExists** — 左側と右側の入力リレーションを取得し、指定された結合変数で定義されている右側のリレーションの値に対応する左側のリレーションの値を保持します。

**** — これはサブクエリのラッパーとして機能するノンブロッキング操作であり、繰り返し実行してループで使用できます。

**DFEMergeChunks** — これは、アップストリームの演算子からのチャンクを 1 つのソリューションのチャンクにまとめて、ダウンストリームの演算子に渡すブロッキング操作です (`DFESplitChunks` の逆)。

**DFEMinus** — 左側と右側の入力リレーションを取得し、指定された結合変数で定義されている右側のリレーションの値に対応しない左側のリレーションの値を保持します。両方のリレーションで変数に重複がない場合、この演算子は単に左側の入力リレーションを返します。

**DFENotExists** — 左側と右側の入力リレーションを取得し、指定された結合変数で定義されている右側のリレーションの値に対応しない左側のリレーションの値を保持します。両方のリレーションで変数に重複がない場合、この演算子は空のリレーションを返します。

**DFEOptionalJoin** — 左外部結合 (OPTIONAL 結合とも呼ばれます) を実行します。右側に少なくとも 1 つの結合パートナーがある左側のソリューションは結合され、右側に結合パートナーがない左側のソリューションはそのまま転送されます。これはブロッキング操作です。

**DFEPipelineJoin** — `pattern` 引数によって定義されたタプルパターンに対して入力を結合します。

**DFEPipelineRangeCount** — 特定のパターンに一致するソリューションの数をカウントし、そのカウント値を含む 1 つの単項ソリューションを返します。

**DFEPipelineScan** — 列に特定のフィルターを適用して、または適用せずに、データベースをスキャンして、指定された `pattern` 引数を探します。

**DFEProject** — 複数の入力列を受け取り、必要な列のみを投影します。

**DFEReduce** — 指定された変数に対して指定された集計関数を実行します。

**DFERelationalJoin** — マージ結合を使用して、指定されたパターンキーに基づいて前の演算子の入力を結合します。これはブロッキング操作です。

**DFERouteChunks** — 入力チャンクを単一の入力エッジから受け取り、これらのチャンクを複数の出力エッジに沿ってルーティングします。

**DFESelectRows** — この演算子は、左側の入力リレーションソリューションから選択的に行を取得し、ダウンストリームの演算子に転送します。行は、演算子の右側の入力リレーションで指定された行識別子に基づいて選択されます。

**DFESerialize** — クエリの最終結果を JSON 文字列としてシリアル化し、各入力ソリューションを適切な変数名にマッピングします。ノードとエッジの結果の場合、これらの結果はエンティティプロパティとメタデータのマップにシリアル化されます。

**DFESort** — 入力リレーションを受け取り、指定されたソートキーに基づいてソートされたリレーションを生成します。

**DFESplitByGroup** — 1 つの入力エッジからの各単一入力チャンクを、別の入力エッジの対応する入力チャンクの行 ID で識別される行グループに対応する小さな出力チャンクに分割します。

**DFESplitChunks** — 各単一入力チャンクをより小さい出力チャンクに分割します (`DFEMergeChunks` の逆)。

**DFEStreamingHashIndexBuild** — `DFEHashIndexBuild` のストリーミングバージョン。

**DFEStreamingGroupByHashIndex** — `DFEGroupByHashIndex` のストリーミングバージョン。

**DFESubquery** — この演算子はすべてのプランの最初に表示され、openCypher のプラン全体である [DFE エンジン](neptune-dfe-engine.md)上で実行されるプランの部分をカプセル化します。

**DFESymmetricHashJoin** — ハッシュ結合を使用して、指定されたパターンキーに基づいて前の演算子の入力を結合します。これは非ブロッキング操作です。

**DFESync** — この演算子は、ノンブロッキングプランをサポートする同期演算子です。2 つの受信エッジからソリューションを受け取り、これらのソリューションを適切なダウンストリームエッジに転送します。同期の目的で、これらのエッジの 1 つに沿った入力は内部でバッファリングされる場合があります。

**DFETee** — これは、同じソリューションセットを複数の演算子に送信する分岐演算子です。

**DFETermResolution** — 入力に対してローカライズ操作またはグローバル化操作を実行し、それぞれローカライズされた識別子またはグローバル化された識別子の列を生成します。

**** — 入力列の値のリストを個別の要素として出力列に展開します。

**DFEunion** — 2 つ以上の入力リレーションを受け取り、目的の出力スキーマを使用して、これらのリレーションの和集合を生成します。

**SolutionInjection** — explain 出力で他のすべての前に表示されます。Units Out 列の値は 1 になります。ただし、これはノーオペレーションとして機能し、実際には DFE エンジンにソリューションは挿入されません。

**TermResolution** — プランの最後に表示され、Neptune エンジンのオブジェクトを openCypher オブジェクトに変換します。

## openCypher `explain` 出力の列
<a name="access-graph-opencypher-explain-columns"></a>

Neptune が openCypher explain 出力として生成するクエリプラン情報には、1 行に 1 つの演算子を含むテーブルが含まれています。このテーブルには、次の列があります。

**ID** — プラン内のこの演算子の数値 ID。

**Out \#1** (および **Out \#2**) — この演算子の下流にいる演算子の ID。ダウンストリーム演算子は最大で 2 つまで存在できます。

**名前** — この演算子の名前。

**引数** — 演算子に関連する詳細。これには、入力スキーマ、出力スキーマ、パターン (`PipelineScan` と`PipelineJoin`) などが含まれます。

**モード** — 基本的な演算子の動作を説明するラベル。この列はほとんど空白 (`-`) です。唯一の例外は `TermResolution` であり、この場合、モードは `id2value_opencypher` になり、ID から openCypher 値への解決を示します。

**Units In** — この演算子への入力として渡されるソリューションの数。`DFEPipelineScan`、`SolutionInjections`、`DFESubquery` など、静的な値が注入されていない上流演算子のない演算子は、ゼロの値を持ちます。

**Units Out** — この演算子の出力として生成されるソリューションの数。`DFEDrain` は特殊なケースであり、排出されるソリューションの数が `Units In` に記録され、`Units Out` は常にゼロになります。

**比率** — `Units In` に対する `Units Out` の比率。

**時間 (ms)** — この演算子が消費した CPU 時間 (ミリ秒単位)。

## openCypher explain 出力の基本的な例
<a name="access-graph-opencypher-explain-basic-example"></a>

openCypher `explain` 出力の基本的な例を次に示します。クエリは、デフォルトの ASCII 出力形式の `details` モード`explain`を使用して `ATL`が呼び出す空港コードを持つノードのエアルートデータセット内の単一ノードルックアップです。

このクエリ`explain`で を呼び出すには:

------
#### [ AWS CLI ]

```
aws neptunedata execute-open-cypher-explain-query \
  --endpoint-url https://{{your-neptune-endpoint}}:{{port}} \
  --open-cypher-query "MATCH (n {code: 'ATL'}) RETURN n" \
  --explain-mode details
```

詳細については、 AWS CLI 「 コマンドリファレンス」の[execute-open-cypher-explain-query](https://docs.aws.amazon.com/cli/latest/reference/neptunedata/execute-open-cypher-explain-query.html)」を参照してください。

------
#### [ SDK ]

```
import boto3
from botocore.config import Config

client = boto3.client(
    'neptunedata',
    endpoint_url='https://{{your-neptune-endpoint}}:{{port}}',
    config=Config(read_timeout=None, retries={'total_max_attempts': 1})
)

response = client.execute_open_cypher_explain_query(
    openCypherQuery="MATCH (n {code: 'ATL'}) RETURN n",
    explainMode='details'
)

print(response['results'].read().decode('utf-8'))
```

他の言語の AWS SDK の例については、「」を参照してください[AWS SDK](access-graph-opencypher-sdk.md)。

------
#### [ awscurl ]

```
awscurl https://{{your-neptune-endpoint}}:{{port}}/openCypher \
  --region {{us-east-1}} \
  --service neptune-db \
  -X POST \
  -d "query=MATCH (n {code: 'ATL'}) RETURN n" \
  -d "explain=details"
```

**注記**  
この例では、 AWS 認証情報が 環境で設定されていることを前提としています。{{us-east-1}} を Neptune クラスターのリージョンに置き換えます。

------
#### [ curl ]

```
curl https://{{your-neptune-endpoint}}:{{port}}/openCypher \
  -d "query=MATCH (n {code: 'ATL'}) RETURN n" \
  -d "explain=details"
```

------

`explain` 出力:

```
Query:
MATCH (n {code: 'ATL'}) RETURN n

╔════╤════════╤════════╤═══════════════════╤════════════════════╤═════════════════════╤══════════╤═══════════╤═══════╤═══════════╗
║ ID │ Out #1 │ Out #2 │ Name              │ Arguments          │ Mode                │ Units In │ Units Out │ Ratio │ Time (ms) ║
╠════╪════════╪════════╪═══════════════════╪════════════════════╪═════════════════════╪══════════╪═══════════╪═══════╪═══════════╣
║ 0  │ 1      │ -      │ SolutionInjection │ solutions=[{}]     │ -                   │ 0        │ 1         │ 0.00  │ 0         ║
╟────┼────────┼────────┼───────────────────┼────────────────────┼─────────────────────┼──────────┼───────────┼───────┼───────────╢
║ 1  │ 2      │ -      │ DFESubquery       │ subQuery=subQuery1 │ -                   │ 0        │ 1         │ 0.00  │ 4.00      ║
╟────┼────────┼────────┼───────────────────┼────────────────────┼─────────────────────┼──────────┼───────────┼───────┼───────────╢
║ 2  │ -      │ -      │ TermResolution    │ vars=[?n]          │ id2value_opencypher │ 1        │ 1         │ 1.00  │ 2.00      ║
╚════╧════════╧════════╧═══════════════════╧════════════════════╧═════════════════════╧══════════╧═══════════╧═══════╧═══════════╝


subQuery1
╔════╤════════╤════════╤═══════════════════════╤══════════════════════════════════════════════════════════════════════════════════════════════════════════════╤══════╤══════════╤═══════════╤═══════╤═══════════╗
║ ID │ Out #1 │ Out #2 │ Name                  │ Arguments                                                                                                    │ Mode │ Units In │ Units Out │ Ratio │ Time (ms) ║
╠════╪════════╪════════╪═══════════════════════╪══════════════════════════════════════════════════════════════════════════════════════════════════════════════╪══════╪══════════╪═══════════╪═══════╪═══════════╣
║ 0  │ 1      │ -      │ DFEPipelineScan       │ pattern=Node(?n) with property 'code' as ?n_code2 and label 'ALL'                                            │ -    │ 0        │ 1         │ 0.00  │ 0.21      ║
║    │        │        │                       │ inlineFilters=[(?n_code2 IN ["ATL"^^xsd:string])]                                                            │      │          │           │       │           ║
║    │        │        │                       │ patternEstimate=1                                                                                            │      │          │           │       │           ║
╟────┼────────┼────────┼───────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 1  │ 2      │ -      │ DFEChunkLocalSubQuery │ subQuery=http://aws.amazon.com/neptune/vocab/v01/dfe/past/graph#9d84f97c-c3b0-459a-98d5-955a8726b159/graph_1 │ -    │ 1        │ 1         │ 1.00  │ 0.04      ║
╟────┼────────┼────────┼───────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 2  │ 3      │ -      │ DFEProject            │ columns=[?n]                                                                                                 │ -    │ 1        │ 1         │ 1.00  │ 0.04      ║
╟────┼────────┼────────┼───────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 3  │ -      │ -      │ DFEDrain              │ -                                                                                                            │ -    │ 1        │ 0         │ 0.00  │ 0.03      ║
╚════╧════════╧════════╧═══════════════════════╧══════════════════════════════════════════════════════════════════════════════════════════════════════════════╧══════╧══════════╧═══════════╧═══════╧═══════════╝


subQuery=http://aws.amazon.com/neptune/vocab/v01/dfe/past/graph#9d84f97c-c3b0-459a-98d5-955a8726b159/graph_1
╔════╤════════╤════════╤══════════════════════╤════════════════════════════════════════════════════════════╤══════╤══════════╤═══════════╤═══════╤═══════════╗
║ ID │ Out #1 │ Out #2 │ Name                 │ Arguments                                                  │ Mode │ Units In │ Units Out │ Ratio │ Time (ms) ║
╠════╪════════╪════════╪══════════════════════╪════════════════════════════════════════════════════════════╪══════╪══════════╪═══════════╪═══════╪═══════════╣
║ 0  │ 1      │ -      │ DFESolutionInjection │ outSchema=[?n, ?n_code2]                                   │ -    │ 0        │ 1         │ 0.00  │ 0.02      ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 1  │ 2      │ 3      │ DFETee               │ -                                                          │ -    │ 1        │ 2         │ 2.00  │ 0.02      ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 2  │ 4      │ -      │ DFEDistinctColumn    │ column=?n                                                  │ -    │ 1        │ 1         │ 1.00  │ 0.20      ║
║    │        │        │                      │ ordered=false                                              │      │          │           │       │           ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 3  │ 5      │ -      │ DFEHashIndexBuild    │ vars=[?n]                                                  │ -    │ 1        │ 1         │ 1.00  │ 0.04      ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 4  │ 5      │ -      │ DFEPipelineJoin      │ pattern=Node(?n) with property 'ALL' and label '?n_label1' │ -    │ 1        │ 1         │ 1.00  │ 0.25      ║
║    │        │        │                      │ patternEstimate=3506                                       │      │          │           │       │           ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 5  │ 6      │ 7      │ DFESync              │ -                                                          │ -    │ 2        │ 2         │ 1.00  │ 0.02      ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 6  │ 8      │ -      │ DFEForwardValue      │ -                                                          │ -    │ 1        │ 1         │ 1.00  │ 0.01      ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 7  │ 8      │ -      │ DFEForwardValue      │ -                                                          │ -    │ 1        │ 1         │ 1.00  │ 0.01      ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 8  │ 9      │ -      │ DFEHashIndexJoin     │ -                                                          │ -    │ 2        │ 1         │ 0.50  │ 0.35      ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 9  │ -      │ -      │ DFEDrain             │ -                                                          │ -    │ 1        │ 0         │ 0.00  │ 0.02      ║
╚════╧════════╧════════╧══════════════════════╧════════════════════════════════════════════════════════════╧══════╧══════════╧═══════════╧═══════╧═══════════╝
```

最上位では、他の何よりも先に `SolutionInjection` が表示され, ユニットアウトは 1 です。実際にはソリューションを注入しないことに注意してください。次の演算子 `DFESubquery` のユニットインは 0 であることがわかります。

最上位の `SolutionInjection` の後は、`DFESubquery` および `TermResolution` 演算子です。`DFESubquery` は、[DFE エンジン](neptune-dfe-engine.md)にプッシュされるクエリ実行プランの一部をカプセル化します (openCypher クエリの場合、クエリプラン全体が DFE によって実行されます)。クエリプラン内のすべての演算子は、`DFESubquery` によって参照される `subQuery1` の内部にネストされています。唯一の例外は `TermResolution` であり、内部 ID を完全にシリアル化された openCypher オブジェクトにマテリアライズします。

DFE エンジンにプッシュされるすべての演算子の名前は `DFE` プレフィックスで始まります。前述のように、openCypher クエリプラン全体が DFE によって実行されるため、結果として、最後の `TermResolution` 演算子を除くすべての演算子は `DFE` で始まります。

`subQuery1` の内部には、メモリ制限のあるメカニズムで実行されるプッシュ実行プランの一部をカプセル化する `DFEChunkLocalSubQuery` または `DFELoopSubQuery` 演算子が 0 個以上存在する可能性があります。`DFEChunkLocalSubQuery` は、ここでは、サブクエリへの入力として使用される 1 つの `SolutionInjection` を含みます。出力でそのサブクエリのテーブルを見つけるには、`DFEChunkLocalSubQuery` または `DFELoopSubQuery` 演算子の `Arguments` 列で指定された `subQuery={{graph URI}}` を検索します。

`subQuery1` では、`ID` が 0 の`DFEPipelineScan` は、データベースをスキャンして、指定された `pattern` を探します。このパターンは、プロパティ `code` が変数 `?n_code2` として保存されているエンティティをすべてのラベルにわたってスキャンします (`airport` を `n:airport` に付加することによって、特定のラベルに絞り込むことができます)。`inlineFilters` 引数は、`code` プロパティが `ATL` に等しい場合のフィルタリングを示します。

次に、`DFEChunkLocalSubQuery` 演算子は `DFEPipelineJoin` を含むサブクエリの中間結果を結合します。これによって、前の `DFEPipelineScan` は `code` プロパティを持つすべてのエンティティをスキャンするため、`?n` が実際にノードであることが保証されます。