INSERT INTO - Amazon Athena

INSERT INTO

ソーステーブルで実行される SELECT クエリステートメント、またはステートメントの一部として提供される VALUES のセットに基づいて、送信先テーブルに新しい行を挿入します。ソーステーブルが CSV や JSON などの形式の基盤データに基づくもので、宛先テーブルが Parquet や ORC など別の形式に基づいている場合は、INSERT INTO クエリを使用して、選択したデータを宛先テーブルの形式に変換できます。

考慮事項と制約事項

Athena で INSERT クエリを使用するときは、以下の点を考慮してください。

  • Amazon S3 で暗号化された基盤データがあるテーブルに対して INSERT クエリを実行する場合、INSERT クエリが書き込む出力ファイルはデフォルトで暗号化されません。暗号化されたデータを含むテーブルに挿入する場合は、INSERT クエリの結果を暗号化することをお勧めします。

    コンソールを使用したクエリ結果の暗号化の詳細については、「Amazon S3 に保存された Athena のクエリ結果の暗号化」を参照してください。AWS CLI または Athena API を使用した暗号化を有効にするには、StartQueryExecution アクションの EncryptionConfiguration プロパティを使用して、要件に沿った Amazon S3 暗号化オプションを指定します。

  • INSERT INTO ステートメントの場合、予想されるバケット所有者の設定は、Amazon S3 内の送信先テーブルのロケーションには適用されません。予期されるバケット所有者の設定は、Athena クエリの結果の出力先として指定した Amazon S3 内の場所にのみ適用されます。詳細については、「Athena コンソールを使用したクエリ結果の場所の指定」を参照してください。

  • ACID 準拠の INSERT INTO ステートメントについては、Iceberg テーブルデータの更新INSERT INTO セクションを参照してください。

サポートされる形式と SerDes

次の形式と SerDes を使用して、データから作成されたテーブルに対して INSERT クエリを実行できます。

データ形式 SerDe

Avro

org.apache.hadoop.hive.serde2.avro.AvroSerDe

Ion com.amazon.ionhiveserde.IonHiveSerDe

JSON

org.apache.hive.hcatalog.data.JsonSerDe

ORC

org.apache.hadoop.hive.ql.io.orc.OrcSerde

Parquet

org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe

テキストファイル

org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe

注記

CSV、TSV、およびカスタム区切りファイルがサポートされています。

バケット化されたテーブルはサポートされていません

INSERT INTO はバケット化されたテーブルではサポートされていません。詳細については、「Athena におけるパーティション化とバケット化」を参照してください。

フェデレーティッドクエリはサポートされていません

横串検索では、INSERT INTO はサポートされていません。これを試みた場合、「This operation is currently not supported for external catalogs (この操作は現在、外部カタログではサポートされていません)」というエラーメッセージが表示されることがあります。横串検索の詳細については、「Amazon Athena 横串検索の使用」を参照してください。

パーティション

INSERT INTO または CREATE TABLE AS SELECT クエリでパーティションを使用するときは、このセクションのポイントを考慮してください。

制限

この INSERT INTO ステートメントは、送信先テーブルへの最大 100  個のパーティションの書き込みをサポートします。100 個を超えるパーティションを持つテーブルから SELECT 句を使用して行を追加する場合、SELECT クエリは、100 個以下のパーティションに制限されない限り失敗します。

この制限を回避する方法については、「CTAS および INSERT INTO を使用して 100 パーティションの制限を回避する」を参照してください。

列の順序

INSERT INTO または CREATE TABLE AS SELECT ステートメントは、SELECT ステートメントで射影された列のリストの最後の列がパーティションされた列であることを期待します。

ソーステーブルがパーティションされていない場合、または宛先テーブルとは異なる列でパーティションされている場合、INSERT INTO destination_table SELECT * FROM source_table のようなクエリは、ソーステーブルの最後の列の値が宛先テーブルのパーティション列の値であると見なします。パーティションされていないテーブルからパーティションテーブルを作成するときは、この点に留意してください。

リソース

パーティションでの INSERT INTO の使用に関する詳細については、以下のリソースを参照してください。

Amazon S3 に書き込まれるファイル

Athena は、INSERT コマンドの結果として、Amazon S3 のソースデータの場所にファイルを書き込みます。INSERT オペレーションごとに、既存のファイルを追加するのではなく、新しいファイルが作成されます。ファイルの場所は、テーブルの構造と SELECT クエリ (存在する場合) に応じて異なります。Athena は、INSERT クエリごとにデータマニフェストファイルを生成します。マニフェストは、クエリが書き込んだファイルを追跡します。これは、Amazon S3 にある Athena のクエリ結果の場所に保存されます。詳細については、「クエリ出力ファイルの識別」を参照してください。

トランザクション集約型更新の回避

INSERT INTO を使用して Amazon S3 内のテーブルに行を追加しても、Athena は既存のファイルの書き換えや変更を行いません。その代わりに、Athena は 1 つ、または複数の新しいファイルとして行を書き込みます。小さなファイルが多数存在するテーブルはクエリパフォーマンスの低下につながりPutObjectGetObject などの書き込みおよび読み取り操作は Amazon S3 のコスト増加につながるため、INSERT INTO を使用するときは以下のオプションを検討してください。

  • 行の大規模なバッチに対する INSERT INTO 操作の実行頻度を減らす。

  • データインジェスト量が多い場合は、Amazon Data Firehose といったサービスの使用を検討する。

  • もとより INSERT INTO を使用しないようにする。その代わりに、より大きなファイルに行を蓄積し、Athena が行をクエリできる Amazon S3 に直接アップロードします。

孤立したファイルの検索

CTAS または INSERT INTO ステートメントが失敗すると、孤立したデータがデータの場所に残され、後続のクエリで読み取られる場合があります。検査または削除する孤立したファイルを見つけるには、Athena に用意されているデータマニフェストファイルを使用して、書き込まれるファイルのリストを追跡できます。詳細については、「クエリ出力ファイルの識別」および「DataManifestLocation」を参照してください。

INSERT INTO...SELECT

1 つのテーブル、source_table に対して実行するクエリを指定します。これにより、2 番目のテーブル、destination_table に挿入する行が決定されます。SELECT クエリが source_table での列を指定する場合、その列は destination_table の列と正確に一致する必要があります。

SELECT クエリの詳細については、「SELECT」を参照してください。

概要

INSERT INTO destination_table SELECT select_query FROM source_table_or_view

vancouver_pageviews テーブル内のすべての行を選択し、canada_pageviews テーブルに挿入します。

INSERT INTO canada_pageviews SELECT * FROM vancouver_pageviews;

date 列の値が 2019-07-012019-07-31vancouver_pageviews テーブル内の行のみを選択し、canada_july_pageviews に挿入します。

INSERT INTO canada_july_pageviews SELECT * FROM vancouver_pageviews WHERE date BETWEEN date '2019-07-01' AND '2019-07-31';

cities_world テーブルの citystate 列で、country 列の値が usa の行だけを選択して、cities_usa テーブルの citystate 列に挿入します。

INSERT INTO cities_usa (city,state) SELECT city,state FROM cities_world WHERE country='usa'

INSERT INTO...VALUES

列と値を指定して、既存のテーブルに行を挿入します。指定された列と関連するデータ型は、宛先テーブルの列およびデータ型と正確に一致する必要があります。

重要

Athena は INSERT オペレーションごとにファイルを生成するため、VALUES を使用した行の挿入は推奨されません。これにより、多数の小さなファイルが作成され、テーブルのクエリパフォーマンスが低下する可能性があります。INSERT クエリが作成するファイルを識別するには、データマニフェストファイルを調べます。詳細については、「クエリ結果、最近のクエリ、および出力ファイルの使用」を参照してください。

概要

INSERT INTO destination_table [(col1,col2,...)] VALUES (col1value,col2value,...)[, (col1value,col2value,...)][, ...]

次の例では、都市テーブルには、idcitystatestate_motto の 3 つの列があります。id 列は INT 型で、他のすべての列は VARCHAR 型です。

cities テーブルに 1 つの行を挿入し、すべての列の値を指定します。

INSERT INTO cities VALUES (1,'Lansing','MI','Si quaeris peninsulam amoenam circumspice')

cities テーブルに 2 行を挿入します。

INSERT INTO cities VALUES (1,'Lansing','MI','Si quaeris peninsulam amoenam circumspice'), (3,'Boise','ID','Esto perpetua')