

# INSERT INTO
<a name="insert-into"></a>

`SELECT` 원본 테이블에서 실행되는 쿼리 설명을 기반으로 하거나 해당 설명의 일부로 제공된 `VALUES` 세트를 기반으로 하는 대상 테이블에 새 행을 삽입합니다. 원본 테이블이 CSV 또는 JSON과 같은 한 가지 형식으로 된 기본 데이터를 기반으로 하고 대상 테이블이 Parquet 또는 ORC와 같은 다른 형식을 기반으로 할 때 `INSERT INTO` 쿼리를 사용하여 선택된 데이터를 대상 테이블의 형식에 맞춰 변환할 수 있습니다.

## 고려 사항 및 제한 사항
<a name="insert-into-limitations"></a>

Athena에서 `INSERT` 쿼리를 사용할 때는 다음 사항을 고려하세요.
+ Amazon S3에서 암호화된 기본 데이터가 포함된 테이블에서 `INSERT` 쿼리를 실행할 때 `INSERT` 쿼리가 작성하는 출력 파일은 기본적으로 암호화되지 않습니다. 암호화된 데이터가 포함된 테이블에 삽입하는 경우 `INSERT` 쿼리 결과를 암호화할 것을 권장합니다.

  콘솔을 사용한 쿼리 결과 암호화에 대한 자세한 내용은 [Amazon S3에 저장된 Athena 쿼리 결과 암호화](encrypting-query-results-stored-in-s3.md) 단원을 참조하세요. AWS CLI 또는 Athena API에서 암호화를 사용하도록 설정하려면 [StartQueryExecution](https://docs.aws.amazon.com/athena/latest/APIReference/API_StartQueryExecution.html) 작업의 `EncryptionConfiguration` 속성을 사용해 필요에 따라 Amazon S3 암호화 옵션을 지정합니다.
+ `INSERT INTO` 문의 경우 예상 버킷 소유자 설정이 Amazon S3의 대상 테이블 위치에 적용되지 않습니다. 예상 버킷 소유자 설정은 Athena 쿼리 결과에 대해 지정한 Amazon S3 출력 위치에만 적용됩니다. 자세한 내용은 [Athena 콘솔을 사용하여 쿼리 결과 위치 지정](query-results-specify-location-console.md) 섹션을 참조하세요.
+ ACID 준수 `INSERT INTO` 문은 [Iceberg 테이블 데이터 업데이트](querying-iceberg-updating-iceberg-table-data.md)의 `INSERT INTO` 단원을 참조하세요.

### 지원되는 형식 및 SerDes
<a name="insert-into-supported-formats"></a>

다음 형식 및 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  TSV 및 사용자 지정 구분 기호로 구분된 파일이 지원됩니다.   | 
| CSV | org.apache.hadoop.hive.serde2.OpenCSVSerde 쓰기는 문자열 유형에서만 지원됩니다. Athena의 경우 Glue 스키마에서 문자열이 아닌 유형이 포함된 테이블에 쓸 수 없습니다. 자세한 내용은 [CSV SerDe](csv-serde.md#csv-serde-opencsvserde-considerations-non-string)를 참조하세요.  | 

### 버킷팅된 테이블은 지원되지 않음
<a name="insert-into-bucketed-tables-not-supported"></a>

`INSERT INTO`은(는) 버킷팅된 테이블에서 지원되지 않습니다. 자세한 내용은 [분할 및 버킷팅 사용](ctas-partitioning-and-bucketing.md) 섹션을 참조하세요.

### 연합 쿼리가 지원되지 않음
<a name="insert-into-federated-queries-not-supported"></a>

연합 쿼리에는 `INSERT INTO`가 지원되지 않습니다. 이를 실행하려고 하면 이 작업은 현재 외부 카탈로그에서 지원되지 않습니다(This operation is currently not supported for external catalogs)라는 오류 메시지가 표시될 수 있습니다. 연합 쿼리에 대한 자세한 내용은 [Amazon Athena 페더레이션 쿼리 사용](federated-queries.md) 섹션을 참조하세요.

### 분할
<a name="insert-into-limitations-partitioning"></a>

`INSERT INTO` 또는 `CREATE TABLE AS SELECT` 쿼리에 분할을 사용할 때 이 단원의 요점들을 고려하세요.

#### 한도
<a name="insert-into-partition-limits"></a>

이 `INSERT INTO` 문은 대상 테이블에 최대 100개의 파티션 쓰기를 지원합니다. 100개 이상의 파티션이 있는 테이블에서 `SELECT` 절을 실행하면 `SELECT` 쿼리가 100개 이하의 파티션으로 제한되지 않는 한 쿼리가 실패합니다.

이 제한을 해결하는 방법에 대한 자세한 내용은 [CTAS 및 INSERT INTO를 사용하여 100개 파티션 한도 문제 해결](ctas-insert-into.md) 단원을 참조하세요.

#### 열 정렬
<a name="insert-into-partition-detection"></a>

`INSERT INTO` 또는 `CREATE TABLE AS SELECT` 문은 분할된 열이 `SELECT` 문에서 프로젝션된 열 목록의 마지막 열이 될 것으로 예상합니다.

소스 테이블이 분할되지 않았거나 대상 테이블과 달리 다른 열에 분할된 경우 `INSERT INTO destination_table SELECT * FROM source_table`와 같은 쿼리는 소스 테이블의 마지막 열 값을 대상 테이블의 파티션 열 값으로 간주합니다. 분할되지 않은 테이블에서 분할된 테이블을 만들려고 할 때는 이 점에 유의해야 합니다.

#### 리소스
<a name="insert-into-partition-resources"></a>

`INSERT INTO`와 파티셔닝 사용에 관한 자세한 내용은 다음 리소스를 참조하세요.
+ 분할된 데이터를 분할된 테이블에 삽입하려면 [CTAS 및 INSERT INTO를 사용하여 100개 파티션 한도 문제 해결](ctas-insert-into.md) 단원을 참조하세요.
+ 분할되지 않은 데이터를 분할된 테이블에 삽입하려면 [ETL 및 데이터 분석에 CTAS 및 INSERT INTO 사용](ctas-insert-into-etl.md) 단원을 참조하세요.

### Amazon S3에 작성되는 파일
<a name="insert-into-files-written-to-s3"></a>

Athena는 Amazon S3의 소스 데이터 위치에 파일을 `INSERT` 명령의 결과로서 작성합니다. 각 `INSERT` 작업은 기존 파일에 추가하는 게 아니라 새 파일을 생성합니다. 파일 위치는 테이블의 구조와 `SELECT` 쿼리(있는 경우)에 따라 달라집니다. Athena는 각 `INSERT` 쿼리에 대해 데이터 매니페스트 파일을 생성합니다. 매니페스트는 쿼리가 작성한 파일을 추적합니다. 이는 Amazon S3의 Athena 쿼리 결과에 저장됩니다. 자세한 내용은 [쿼리 출력 파일 식별](querying-finding-output-files.md#querying-identifying-output-files) 섹션을 참조하세요.

### 트랜잭션이 많은 업데이트 방지
<a name="insert-into-transactional-caveat"></a>

`INSERT INTO`를 사용하여 Amazon S3의 테이블에 행을 추가할 때 Athena는 기존 파일을 다시 쓰거나 수정하지 않습니다. 대신 행을 하나 이상의 새 파일로 씁니다. [작은 파일이 많은 테이블은 쿼리 성능을 저하시키고](performance-tuning-data-optimization-techniques.md#performance-tuning-avoid-having-too-many-files), `PutObject` 및 `GetObject`와 같은 쓰기 및 읽기 작업을 수행하면 Amazon S3에서 비용이 증가하므로 `INSERT INTO` 사용 시에는 다음 사항을 고려하세요.
+ 대량의 행 배치에서는 `INSERT INTO` 작업 실행 빈도를 줄이세요.
+ 데이터 모으기 양이 많은 경우 [Amazon Data Firehose](https://docs.aws.amazon.com/firehose/latest/dev/what-is-this-service.html)와 같은 서비스를 사용해 보세요.
+ `INSERT INTO`를 함께 사용하지 마세요. 대신 행을 큰 파일로 모아 Athena가 쿼리할 수 있도록 Amazon S3에 직접 업로드하세요.

### 분리된 파일 찾기
<a name="insert-into-files-partial-data"></a>

`CTAS` 또는 `INSERT INTO` 문이 실패하는 경우 분리된 데이터가 해당 데이터 위치에 남을 수 있고 후속 쿼리에서 이 데이터를 읽을 수 있습니다. 검사 또는 삭제할 분리된 파일을 찾으려면 Athena에서 제공하는 데이터 매니페스트 파일을 사용하여 작성할 파일 목록을 추적할 수 있습니다. 자세한 내용은 [쿼리 출력 파일 식별](querying-finding-output-files.md#querying-identifying-output-files) 및 [DataManifestLocation](https://docs.aws.amazon.com/athena/latest/APIReference/API_QueryExecutionStatistics.html#athena-Type-QueryExecutionStatistics-DataManifestLocation)를 참조하세요.

## INSERT INTO...SELECT
<a name="insert-into-select"></a>

쿼리가 하나의 테이블 `source_table`에서 실행되도록 지정하면 두 번째 테이블 `destination_table`에 삽입할 행이 결정됩니다. `SELECT` 쿼리가 `source_table`의 열을 지정하는 경우 해당 열은 `destination_table`의 열과 정확하게 일치해야 합니다.

`SELECT` 쿼리에 대한 자세한 내용은 [SELECT](select.md) 단원을 참조하세요.

### 시놉시스
<a name="insert-into-select-synopsis"></a>

```
INSERT INTO destination_table 
SELECT select_query 
FROM source_table_or_view
```

### 예제
<a name="insert-into-select-examples"></a>

`vancouver_pageviews` 테이블의 모든 행을 선택한 다음 `canada_pageviews` 테이블에 삽입합니다.

```
INSERT INTO canada_pageviews 
SELECT * 
FROM vancouver_pageviews;
```

`2019-07-01`에서 `2019-07-31` 사이의 값이 포함된 `date` 열이 있는 `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';
```

`country` 열에 `usa`의 값이 포함된 행에서 `cities_world` 테이블의 `city` 및 `state` 열의 값을 선택한 다음 `cities_usa` 테이블의 `city` 및 `state` 열에 삽입합니다.

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

## INSERT INTO...VALUES
<a name="insert-into-values"></a>

열 및 값을 지정하여 기존 테이블에 행을 삽입합니다. 지정된 열 및 관련 데이터 형식은 대상 테이블의 열 및 데이터 형식과 정확하게 일치해야 합니다.

**중요**  
Athena는 각 `INSERT` 작업에 대해 파일을 생성하기 때문에 `VALUES`를 사용하여 행을 삽입하는 것은 권장하지 않습니다. 이로 인해 작은 파일이 많이 생성되어 테이블의 쿼리 성능이 저하될 수 있습니다. `INSERT` 쿼리가 생성하는 파일을 식별하려면 데이터 매니페스트 파일을 검사합니다. 자세한 내용은 [쿼리 결과 및 최근 쿼리 작업](querying.md) 섹션을 참조하세요.

### 시놉시스
<a name="insert-into-values-synopsis"></a>

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

### 예제
<a name="insert-into-values-examples"></a>

다음 예시에서 도시 테이블에는 `id`, `city`, `state`, `state_motto`의 세 가지 열이 있습니다. `id` 열은 `INT` 형식이고 기타 모든 열은 `VARCHAR` 형식입니다.

`cities` 테이블에 단일 행 하나를 삽입하고 모든 열 값을 지정합니다.

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

`cities` 테이블에 행 두 개를 삽입합니다.

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