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
はバケット化されたテーブルではサポートされていません。詳細については、「パーティショニングとバケット化を使用する」を参照してください。
フェデレーティッドクエリはサポートされていません
横串検索では、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
の使用に関する詳細については、以下のリソースを参照してください。
-
パーティションされたデータをパーティションテーブルに挿入する方法については、「CTAS および INSERT INTO を使用して 100 パーティションの制限を回避する」を参照してください。
-
パーティションされていないデータをパーティションテーブルに挿入する方法については、「ETL およびデータ分析での CTAS および INSERT INTO を使用する」を参照してください。
Amazon S3 に書き込まれるファイル
Athena は、INSERT
コマンドの結果として、Amazon S3 のソースデータの場所にファイルを書き込みます。INSERT
オペレーションごとに、既存のファイルを追加するのではなく、新しいファイルが作成されます。ファイルの場所は、テーブルの構造と SELECT
クエリ (存在する場合) に応じて異なります。Athena は、INSERT
クエリごとにデータマニフェストファイルを生成します。マニフェストは、クエリが書き込んだファイルを追跡します。これは、Amazon S3 にある Athena のクエリ結果の場所に保存されます。詳細については、「クエリ出力ファイルを識別する」を参照してください。
トランザクション集約型更新の回避
INSERT INTO
を使用して Amazon S3 内のテーブルに行を追加しても、Athena は既存のファイルの書き換えや変更を行いません。その代わりに、Athena は 1 つ、または複数の新しいファイルとして行を書き込みます。小さなファイルが多数存在するテーブルはクエリパフォーマンスの低下につながり、PutObject
や GetObject
などの書き込みおよび読み取り操作は 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-01
~2019-07-31
の vancouver_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
テーブルの city
と state
列で、country
列の値が usa
の行だけを選択して、cities_usa
テーブルの city
と state
列に挿入します。
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,...)][,
...]
例
次の例では、都市テーブルには、id
、city
、state
、state_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')