

# Athena EXPLAIN ステートメントの結果を理解する
<a name="athena-explain-statement-understanding"></a>

このトピックでは、Athena `EXPLAIN` ステートメントの結果で使用されるオペレーション用語の概要を説明します。

## EXPLAIN ステートメントの出力タイプ
<a name="athena-explain-statement-understanding-explain-plan-types"></a>

`EXPLAIN` ステートメントの出力は、以下の 2 つのタイプのいずれかになります。
+ **論理プラン** – SQL エンジンがステートメントの実行に使用する論理プランを表示します。このオプションの構文は `EXPLAIN` または `EXPLAIN (TYPE LOGICAL)` です。
+ **分散プラン** – 分散環境での実行プランを表示します。出力には、処理ステージであるフラグメントが表示されます。各プランフラグメントは、1 つ、または複数のノードによって処理されます。データは、フラグメントを処理するノード間で交換できます。このオプションの構文は `EXPLAIN (TYPE DISTRIBUTED)` です。

  分散プランの出力では、フラグメント (処理ステージ) は `Fragment` *number* [*fragment\$1type*] により表されます。この時、*number* はゼロから始まる整数であり、*fragment\$1type* はフラグメントがノードによってどのように実行されるかを指定します。以下の表では、データ交換のレイアウトに関する洞察を提供するフラグメントタイプが説明されています。  
**分散プランのフラグメントタイプ**    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/athena/latest/ug/athena-explain-statement-understanding.html)

## Exchange
<a name="athena-explain-statement-understanding-exchange-types"></a>

Exchange 関連の用語は、データがワーカーノード間でどのように交換されるかを表します。転送はローカルまたはリモートのいずれかです。

**LocalExchange [*exchange\$1type*] **  
クエリのさまざまなステージで、データをワーカーノード内でローカルに転送します。*exchange\$1type* の値は、このセクションで後ほど説明する論理交換タイプまたは分散交換タイプのいずれかになります。

**RemoteExchange [*exchange\$1type*] **  
クエリのさまざまなステージで、データをワーカーノード間で転送します。*exchange\$1type* の値は、このセクションで後ほど説明する論理交換タイプまたは分散交換タイプのいずれかになります。

### 論理交換タイプ
<a name="athena-explain-statement-understanding-exchange-types-logical"></a>

以下の交換タイプは、論理プランの交換フェーズで実行されるアクションを説明します。
+ **`GATHER`** – 単一のワーカーノードが、他のすべてのワーカーノードからの出力を収集します。例えば、選択クエリの最後のステージでは、すべてのノードから結果が収集され、その結果が Amazon S3 に書き込まれます。
+ **`REPARTITION`** – 次の演算子への適用に必要なパーティショニングスキームに基づいて、行データを特定のワーカーに送信します。
+ **`REPLICATE`** – 行データをすべてのワーカーにコピーします。

### 分散交換タイプ
<a name="athena-explain-statement-understanding-exchange-types-distributed"></a>

以下の交換タイプは、データが分散プラン内のノード間で交換されるときのデータのレイアウトを示します。
+ **`HASH`** – この交換は、ハッシュ関数を使用して複数の宛先にデータを分散します。
+ **`SINGLE`** – この交換は、データを単一の宛先に分散します。

## スキャニング
<a name="athena-explain-statement-understanding-scanning"></a>

以下の用語は、クエリ中にデータがどのようにスキャンされるかを説明します。

**TableScan **  
Amazon S3 または Apache Hive コネクタからテーブルのソースデータをスキャンし、フィルタ述語から生成されたパーティションプルーニングを適用します。

**ScanFilter **  
Amazon S3 または Hive コネクタからテーブルのソースデータをスキャンし、フィルタ述語から生成されたパーティションプルーニングと、パーティションプルーニング経由で適用されない追加のフィルタ述語から生成されたパーティションプルーニングを適用します。

**ScanFilterProject **  
最初に、Amazon S3 または Hive コネクタからテーブルのソースデータをスキャンし、フィルタ述語から生成されたパーティションプルーニングと、パーティションプルーニング経由で適用されない追加のフィルタ述語から生成されたパーティションプルーニングを適用します。次に、出力データのメモリレイアウトを新しい射影に変更して、後続ステージのパフォーマンスを向上させます。

## 結合
<a name="athena-explain-statement-understanding-join"></a>

2 つのテーブル間でデータを結合します。結合は、結合タイプおよび分散タイプ別に分類できます。

### 結合の種類
<a name="athena-explain-statement-understanding-join-types"></a>

結合タイプは、結合オペレーションの実行方法を定義します。

**CrossJoin** – 結合された 2 つのテーブルのデカルト積を生成します。

**InnerJoin** – 両方のテーブルに一致する値を持つレコードを選択します。

**LeftJoin** – 左側のテーブルからのすべてのレコードと、右側のテーブルからの一致するレコードを選択します。一致するレコードがない場合、右側の結果は NULL になります。

**RightJoin** – 右側のテーブルからのすべてのレコードと、左側のテーブルからの一致するレコードを選択します。一致するレコードがない場合、左側の結果は NULL になります。

**FullJoin** – 左または右のテーブルのレコードに一致するものがあるすべてのレコードを選択します。結合されたテーブルには両方のテーブルからのすべてのレコードが含まれ、どちらかのテーブルで一致するレコードが欠落していれば NULL が入力されます。

**注記**  
パフォーマンス上の理由から、クエリエンジンは、結合クエリを異なる結合タイプに書き直して、同じ結果を生成することができます。例えば、1 つのテーブルでの述語を使用した内部結合クエリは、`CrossJoin` に書き直すことができます。これは、スキャンされるデータを少なくするために、述語をテーブルのスキャンフェーズにプッシュダウンします。

### 結合の分散タイプ
<a name="athena-explain-statement-understanding-join-distribution-types"></a>

分散タイプは、結合オペレーションの実行時に、データがワーカーノード間でどのように交換されるかを定義します。

**パーティション** – 左と右の両方のテーブルが、すべてのワーカーノード全体でハッシュパーティション分割されます。パーティション分散では、各ノードで消費されるメモリが少なくなります。パーティション分散は、レプリケート結合よりもはるかに遅くなる可能性があります。パーティション結合は、2 つの大きなテーブルを結合する場合に適しています。

**レプリケート** – 一方のテーブルがすべてのワーカーノード全体でハッシュパーティション分割され、もう一方のテーブルは、結合操作を実行するために、すべてのワーカーノードにレプリケートされます。レプリケート分散はパーティション結合よりもはるかに高速ですが、各ワーカーノードで消費されるメモリが多くなります。レプリケートされたテーブルが大きすぎる場合は、ワーカーノードでメモリ不足エラーが発生する可能性があります。レプリケート結合は、結合されたテーブルの 1 つが小さい場合に適しています。