CTAS 및 INSERT INTO를 사용하여 100개 파티션 한도 해결 - Amazon Athena

CTAS 및 INSERT INTO를 사용하여 100개 파티션 한도 해결

Athena는 CREATE TABLE AS SELECT(CTAS) 쿼리당 파티션을 100개로 제한합니다. 마찬가지로, INSERT INTO 문을 통해 대상 테이블에 최대 100개의 파티션을 추가할 수 있습니다.

이 제한을 초과하면 “HIVE_TOO_MANY_OPEN_파티션: 파티션/버킷에 대해 열린 작성자 100개를 초과했습니다.”라는 오류 메시지가 표시될 수 있습니다. 이러한 제한은 CTAS 문(최대 100개의 파티션 생성) 및 일련의 INSERT INTO 문(각각 최대 100개의 파티션 삽입)을 사용하여 해결할 수 있습니다.

이 주제의 예제에서는 Amazon S3 버킷 위치(s3://DOC-EXAMPLE-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://DOC-EXAMPLE-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 조건을 설정할 때 쿼리가 중첩되지 않도록 해야 합니다. 그렇지 않으면 일부 파티션에 중복된 데이터가 있을 수 있습니다.