

# CTAS 및 INSERT INTO를 사용하여 100개 파티션 한도 문제 해결
<a name="ctas-insert-into"></a>

Athena는 `CREATE TABLE AS SELECT`([CTAS](ctas.md)) 쿼리당 파티션을 100개로 제한합니다. 마찬가지로, [INSERT INTO](https://docs.aws.amazon.com/athena/latest/ug/insert-into.html) 문을 통해 대상 테이블에 최대 100개의 파티션을 추가할 수 있습니다.

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

이 주제의 예제에서는 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/'
   ```

1. 다음과 유사한 `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
   */
   ```

1. CTAS 쿼리를 실행하여 분할된 테이블을 생성합니다.

   다음 예제에서는 `my_lineitem_parq_partitioned`라는 테이블을 만들고 `WHERE ` 절을 사용하여 `DATE`를 `1992-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');
   ```

1. `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
   */
   ```

1. `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');
   ```

1. `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
   */
   ```

1. 각 파티션에 100개 이하의 파티션을 읽고 추가하는 `INSERT INTO` 문을 계속 사용합니다. 필요한 파티션 수에 도달할 때까지 계속합니다.
**중요**  
`WHERE` 조건을 설정할 때 쿼리가 중첩되지 않도록 해야 합니다. 그렇지 않으면 일부 파티션에 중복된 데이터가 있을 수 있습니다.