CTAS および INSERT INTO を使用して 100 パーティションの制限を回避する - Amazon Athena

CTAS および INSERT INTO を使用して 100 パーティションの制限を回避する

Athena では、CREATE TABLE AS SELECT (CTAS) クエリごとのパーティション数は 100 個に制限されています。同様に、INSERT INTO ステートメントを使用すると、宛先テーブルに最大 100 個のパーティションを追加できます。

この制限を超えると、HIVE_TOO_MANY_OPEN_PARTITIONS: Exceeded limit of 100 open writers for partitions/buckets (HIVE_TOO_MANY_OPEN_PARTITIONS: パーティション/バケットのオープンライターの制限である 100 を超えました) エラーメッセージが表示されることがあります。これらの制限を回避するには、CTAS ステートメントと、それぞれ最大 100 個のパーティションを作成または挿入する一連の INSERT INTO ステートメントを使用できます。

このトピックの例では、Amazon S3 バケットの場所 s3://amzn-s3-demo-bucket/ にデータが格納されている、tpch100 という名前のデータベースを使用します。

CTAS および INSERT INTO を使用して 100 個を超えるパーティションのテーブルを作成するには
  1. CREATE EXTERNAL TABLE ステートメントを使用して、目的のフィールドでパーティション化されたテーブルを作成します。

    次の例のステートメントは、列 l_shipdate でデータを分割します。テーブルには 2525 個のパーティションがあります。

    CREATE EXTERNAL TABLE `tpch100.lineitem_parq_partitioned`( `l_orderkey` int, `l_partkey` int, `l_suppkey` int, `l_linenumber` int, `l_quantity` double, `l_extendedprice` double, `l_discount` double, `l_tax` double, `l_returnflag` string, `l_linestatus` string, `l_commitdate` string, `l_receiptdate` string, `l_shipinstruct` string, `l_comment` string) PARTITIONED BY ( `l_shipdate` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://amzn-s3-demo-bucket/lineitem/'
  2. 次のような SHOW PARTITIONS <table_name> コマンドを実行して、パーティションをリストします。

    SHOW PARTITIONS lineitem_parq_partitioned

    次に、結果の一部を示します。

    /* l_shipdate=1992-01-02 l_shipdate=1992-01-03 l_shipdate=1992-01-04 l_shipdate=1992-01-05 l_shipdate=1992-01-06 ... l_shipdate=1998-11-24 l_shipdate=1998-11-25 l_shipdate=1998-11-26 l_shipdate=1998-11-27 l_shipdate=1998-11-28 l_shipdate=1998-11-29 l_shipdate=1998-11-30 l_shipdate=1998-12-01 */
  3. CTAS クエリを実行して、パーティション分割されたテーブルを作成します。

    次の例では、my_lineitem_parq_partitioned というテーブルを作成し、WHERE 句を使用して、DATE1992-02-01 より前の日付に制限します。サンプルデータセットは 1992 年 1 月から始まるため、1992 年 1 月のパーティションのみが作成されます。

    CREATE table my_lineitem_parq_partitioned WITH (partitioned_by = ARRAY['l_shipdate']) AS SELECT l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_commitdate, l_receiptdate, l_shipinstruct, l_comment, l_shipdate FROM tpch100.lineitem_parq_partitioned WHERE cast(l_shipdate as timestamp) < DATE ('1992-02-01');
  4. SHOW PARTITIONS コマンドを実行して、必要なパーティションがテーブルに含まれていることを確認します。

    SHOW PARTITIONS my_lineitem_parq_partitioned;

    この例のパーティションは 1992 年 1 月のものです。

    /* l_shipdate=1992-01-02 l_shipdate=1992-01-03 l_shipdate=1992-01-04 l_shipdate=1992-01-05 l_shipdate=1992-01-06 l_shipdate=1992-01-07 l_shipdate=1992-01-08 l_shipdate=1992-01-09 l_shipdate=1992-01-10 l_shipdate=1992-01-11 l_shipdate=1992-01-12 l_shipdate=1992-01-13 l_shipdate=1992-01-14 l_shipdate=1992-01-15 l_shipdate=1992-01-16 l_shipdate=1992-01-17 l_shipdate=1992-01-18 l_shipdate=1992-01-19 l_shipdate=1992-01-20 l_shipdate=1992-01-21 l_shipdate=1992-01-22 l_shipdate=1992-01-23 l_shipdate=1992-01-24 l_shipdate=1992-01-25 l_shipdate=1992-01-26 l_shipdate=1992-01-27 l_shipdate=1992-01-28 l_shipdate=1992-01-29 l_shipdate=1992-01-30 l_shipdate=1992-01-31 */
  5. INSERT INTO ステートメントを使用して、テーブルにパーティションを追加します。

    次の例では、1992 年 2 月の日付のパーティションを追加します。

    INSERT INTO my_lineitem_parq_partitioned SELECT l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_commitdate, l_receiptdate, l_shipinstruct, l_comment, l_shipdate FROM tpch100.lineitem_parq_partitioned WHERE cast(l_shipdate as timestamp) >= DATE ('1992-02-01') AND cast(l_shipdate as timestamp) < DATE ('1992-03-01');
  6. SHOW PARTITIONS をもう一度実行します。

    SHOW PARTITIONS my_lineitem_parq_partitioned;

    サンプルテーブルには、1992 年 1 月と 2 月のパーティションがあります。

    /* l_shipdate=1992-01-02 l_shipdate=1992-01-03 l_shipdate=1992-01-04 l_shipdate=1992-01-05 l_shipdate=1992-01-06 ... l_shipdate=1992-02-20 l_shipdate=1992-02-21 l_shipdate=1992-02-22 l_shipdate=1992-02-23 l_shipdate=1992-02-24 l_shipdate=1992-02-25 l_shipdate=1992-02-26 l_shipdate=1992-02-27 l_shipdate=1992-02-28 l_shipdate=1992-02-29 */
  7. 各々が読み取りと追加を 100 パーティション以上実行しない INSERT INTO ステートメントを引き続き使用します。必要なパーティション数に達するまで続行します。

    重要

    WHERE 条件を設定するときは、クエリが重複しないようにしてください。そうしなければ、一部のパーティションに重複するデータが発生する可能性があります。