

# DML 쿼리, 함수 및 연산자
<a name="dml-queries-functions-operators"></a>

Athena DML 쿼리 엔진에서는 일반적으로 Trino 및 Presto 구문을 지원하며 자체 개선 사항을 추가합니다. Trino 또는 Presto의 일부 기능은 Athena에서 지원되지 않습니다. 자세한 내용은 이 단원의 특정 문에 대한 주제 및 [고려 사항 및 제한 사항](other-notable-limitations.md)을 참조하세요. 함수에 대한 자세한 내용은 [Amazon Athena의 함수](functions.md) 섹션을 참조하세요. Athena 엔진 버전에 대한 자세한 내용은 [Athena 엔진 버전 관리](engine-versions.md) 단원을 참조하세요.

DDL 문에 대한 자세한 내용은 [DDL 문](ddl-reference.md) 단원을 참조하세요. 지원되지 않는 DDL 문의 목록은 [지원되지 않는 DDL](unsupported-ddl.md) 단원을 참조하세요.

**Topics**
+ [SELECT](select.md)
+ [INSERT INTO](insert-into.md)
+ [VALUES](values-statement.md)
+ [DELETE](delete-statement.md)
+ [UPDATE](update-statement.md)
+ [MERGE INTO](merge-into-statement.md)
+ [OPTIMIZE](optimize-statement.md)
+ [VACUUM](vacuum-statement.md)
+ [EXPLAIN 및 EXPLAIN ANALYZE](athena-explain-statement.md)
+ [PREPARE](sql-prepare.md)
+ [UNLOAD](unload.md)
+ [함수](functions.md)
+ [지원되는 시간대 사용](athena-supported-time-zones.md)

# SELECT
<a name="select"></a>

0개 이상의 테이블에서 데이터 행을 검색합니다.

**참고**  
이 주제에서는 참조할 수 있는 요약 정보를 제공합니다. `SELECT` 및 SQL 언어에 대한 포괄적인 정보는 이 설명서에서 다루지 않습니다. Athena와 관련된 SQL 사용에 대한 자세한 내용은 [Amazon Athena의 SQL 쿼리에 대한 고려 사항 및 제한 사항](other-notable-limitations.md) 및 [Amazon Athena에서 SQL 쿼리 실행](querying-athena-tables.md) 단원을 참조하세요. 데이터베이스 생성, 테이블 생성 및 Athena의 테이블에서 `SELECT` 쿼리 실행에 대한 예제는 [시작하기](getting-started.md) 항목을 참조하세요.

## 시놉시스
<a name="synopsis"></a>

```
[ WITH with_query [, ...] ]
SELECT [ ALL | DISTINCT ] select_expression [, ...]
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY [ ALL | DISTINCT ] grouping_element [, ...] ]
[ HAVING condition ]
[ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ]
[ ORDER BY expression [ ASC | DESC ] [ NULLS FIRST | NULLS LAST] [, ...] ]
[ OFFSET count [ ROW | ROWS ] ]
[ LIMIT [ count | ALL ] ]
```

**참고**  
SQL SELECT 문의 예약어는 큰따옴표로 묶어야 합니다. 자세한 내용은 [SQL SELECT 문에서 이스케이프할 예약어](reserved-words.md#list-of-reserved-words-sql-select) 섹션을 참조하세요.

## 파라미터
<a name="select-parameters"></a>

**[ WITH with\$1query [, ....] ]**  
`WITH`를 사용하여 중첩 쿼리를 평면화하거나 하위 쿼리를 단순화할 수 있습니다.  
Athena 엔진 버전 3부터 `WITH` 절을 사용하여 재귀 쿼리를 생성하는 작업이 지원됩니다. 최대 재귀 깊이는 10입니다.  
`WITH` 절은 쿼리에서 `SELECT` 목록에 선행하고 `SELECT` 쿼리 내에서 사용할 하나 이상의 하위 쿼리를 정의합니다.  
각각의 하위 쿼리는 `FROM` 절에서 참조할 수 있는 뷰 정의와 비슷한 임시 테이블을 정의합니다. 이러한 테이블은 쿼리를 실행할 때만 사용됩니다.  
`with_query` 구문은 다음과 같습니다.  

```
subquery_table_name [ ( column_name [, ...] ) ] AS (subquery)
```
위치:  
+  `subquery_table_name`은 `WITH` 절 하위 쿼리의 결과를 정의하는 임시 테이블의 고유한 이름입니다. 각각의 `subquery`에는 `FROM` 절에서 참조될 수 있는 테이블 이름이 있어야 합니다.
+  `column_name [, ...]`은 출력 열 이름의 선택적 목록입니다. 열 이름의 수는 `subquery`로 정의되는 열 개수보다 적거나 같아야 합니다.
+  `subquery`는 임의의 쿼리 설명문입니다.

**[ ALL \$1 DISTINCT ] select\$1expression**  
 `select_expression`는 선택하려는 행을 결정합니다. `select_expression`은 다음 형식 중 하나를 사용할 수 있습니다.  

```
expression [ [ AS ] column_alias ] [, ...]
```

```
row_expression.* [ AS ( column_alias [, ...] ) ]
```

```
relation.*
```

```
*
```
+ `expression [ [ AS ] column_alias ]` 구문은 출력 열을 지정합니다. 선택적 `[AS] column_alias` 구문은 출력에서 열에 사용할 사용자 지정 제목 이름을 지정합니다.
+ `row_expression.* [ AS ( column_alias [, ...] ) ]`의 경우에, `row_expression`은 임의의 데이터 유형 `ROW`의 표현식입니다. 행의 필드는 결과에 포함할 출력 열을 정의합니다.
+ `relation.*`의 경우, `relation`의 열이 결과에 포함됩니다. 이 구문에서는 열 별칭을 사용할 수 없습니다.
+ 별표 `*`는 모든 열이 결과 집합에 포함되도록 지정합니다.
+ 결과 집합에서 열의 순서는 select 표현식이 지정한 순서와 동일합니다. select 표현식이 여러 열을 반환하는 경우 열 순서는 소스 관계 또는 행 유형 표현식에 사용된 순서를 따릅니다.
+ 열 별칭을 지정하면 별칭이 기존 열 또는 행 필드 이름보다 우선합니다. select 표현식에 열 이름이 없는 경우 인덱스가 0인 익명 열 이름(`_col0`, `_col1`, `_col2, ...`)이 출력에 표시됩니다.
+  기본값은 `ALL`입니다. `ALL`을 사용하면 마치 생략된 것처럼 처리됩니다. 모든 열에 대한 모든 행이 선택되고 중복이 유지됩니다.
+ 열에 중복된 값이 포함되어 있는 경우 고유 값만 반환하려면 `DISTINCT`를 사용합니다.

**FROM from\$1item [, ...]**  
아래에 설명된 대로 `from_item`이 뷰, 조인 생성 또는 하위 쿼리가 될 수 있는 쿼리 입력을 나타냅니다.  
`from_item`은 다음 중 하나일 수 있습니다.  
+  `table_name [ [ AS ] alias [ (column_alias [, ...]) ] ]` 

  `table_name`이 행을 선택할 대상 테이블의 이름인 경우 `alias`는 `SELECT` 설명의 출력을 제공할 이름이고 `column_alias`는 지정된 `alias`에 대한 열을 정의합니다.
 **-또는-**   
+  `join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]` 

  여기에서 `join_type`은 다음 중 하나입니다.
  +  `[ INNER ] JOIN` 
  +  `LEFT [ OUTER ] JOIN` 
  +  `RIGHT [ OUTER ] JOIN` 
  +  `FULL [ OUTER ] JOIN` 
  +  `CROSS JOIN` 
  +  `ON join_condition | USING (join_column [, ...])` `join_condition`을 사용하면 여러 테이블의 조인 키에 열 이름을 지정할 수 있으며 `join_column`을 사용하려면 `join_column`가 두 테이블에 모두 존재해야 합니다.

**[ WHERE condition ]**  
사용자가 지정한 `condition`에 따라 결과를 필터링합니다. 여기서 `condition`에는 일반적으로 다음과 같은 구문이 있습니다.  

```
column_name operator value [[[AND | OR] column_name operator value] ...]
```
*연산자*는 비교 연산자(`=`, `>`, `<`, `>=`, `<=`, `<>`, `!=`) 중 하나일 수 있습니다.  
다음 하위 쿼리 표현식은 `WHERE`절에서 사용할 수도 있습니다.  
+ `[NOT] BETWEEN integer_A AND integer_B` – 다음 예시처럼 두 정수 사이의 범위를 지정합니다. 열 데이터 형식이 `varchar`인 경우 먼저 열을 정수로 변환해야 합니다.

  ```
  SELECT DISTINCT processid FROM "webdata"."impressions"
  WHERE cast(processid as int) BETWEEN 1500 and 1800
  ORDER BY processid
  ```
+ `[NOT] LIKE value` - 지정된 패턴을 검색합니다. 다음 예시와 같이 백분율 기호(`%`)를 와일드카드 문자로 사용할 수 있습니다.

  ```
  SELECT * FROM "webdata"."impressions"
  WHERE referrer LIKE '%.org'
  ```
+ `[NOT] IN (value[, value[, ...])` - 다음 예시와 같이 열에 사용 가능한 값 목록을 지정합니다.

  ```
  SELECT * FROM "webdata"."impressions"
  WHERE referrer IN ('example.com','example.net','example.org')
  ```

**[ GROUP BY [ ALL \$1 DISTINCT ] grouping\$1expressions [, ...] ]**  
`SELECT` 설명의 출력을 일치하는 값의 행으로 나눕니다.  
 `ALL` 및 `DISTINCT`는 중복되는 그룹화 집합이 각각 다른 출력 행을 생성할지 결정합니다. 생략된 경우, `ALL`로 간주됩니다.  
`grouping_expressions`를 사용하면 복합 그룹화 작업을 수행할 수 있습니다. 복합 그룹화(complex grouping) 연산을 수행하면 하나의 쿼리에 여러 집합을 집계해야 하는 분석을 수행할 수 있습니다.  
`grouping_expressions` 요소는 다음과 입력 열에서 수행되는 모든 함수(예: `SUM`, `AVG`, 또는 `COUNT`)일 수 있습니다.  
`GROUP BY` 식은 `SELECT` 설명 출력에 나타나지 않는 입력 열 이름별로 출력을 그룹화할 수 있습니다.  
모든 출력 식은 집계 함수이거나 `GROUP BY` 절에 있는 열이어야 합니다.  
단일 쿼리를 사용하여 여러 열 집합을 집계해야 하는 분석을 수행할 수 있습니다.  
Athena는 `GROUPING SETS`, `CUBE`, `ROLLUP`을 사용한 복합적 집계를 지원합니다. `GROUP BY GROUPING SETS`은 그룹화할 여러 열 목록을 지정합니다. `GROUP BY CUBE`은 주어진 열 집합에 대해 가능한 모든 그룹화 집합을 생성합니다. `GROUP BY ROLLUP`은 주어진 열 집합에 대해 가능한 모든 소계를 생성합니다. 복합 그룹화 연산은 입력 열로 구성된 표현식에 대해 그룹화를 지원하지 않습니다. 열 이름만 허용됩니다.  
흔히 `UNION ALL`을 사용해도 이러한 `GROUP BY` 작업과 동일한 결과를 얻을 수 있지만 `GROUP BY`를 사용하는 쿼리는 데이터를 한 번만 읽는 이점이 있는 데 비해 `UNION ALL`은 기본 데이터를 세 번 읽으며, 데이터 원본이 변경될 경우 일관성 없는 결과를 생성할 수 있습니다.

**[ HAVING condition ]**  
집계 함수 및 `GROUP BY` 절과 함께 사용됩니다. `condition`을 만족하지 않는 그룹을 제거하여 어떤 그룹을 선택할지 제어합니다. 이 필터링은 그룹과 집계 처리가 완료된 후 적용됩니다.

**[ \$1 UNION \$1 INTERSECT \$1 EXCEPT \$1 [ ALL \$1 DISTINCT ] union\$1query] ]**  
`UNION`, `INTERSECT`, `EXCEPT`는 둘 이상의 `SELECT` 문 결과를 하나의 쿼리로 결합합니다. `ALL` 또는 `DISTINCT`는 최종 결과 집합에 포함된 열의 고유성을 제어합니다.  
`UNION`은 첫 번째 쿼리의 결과 행을 두 번째 쿼리의 결과 행과 결합합니다. 중복된 항목을 제거하기 위해 `UNION`은 메모리를 소비하는 해시 테이블을 빌드합니다. 쿼리에서 중복 항목을 제거할 필요가 없는 경우 성능 향상을 위해 `UNION ALL`을 사용하는 것이 좋습니다. 다중 `UNION` 절은 괄호를 사용하여 처리 순서를 명시적으로 정의하지 않는 한 왼쪽에서 오른쪽으로 처리됩니다.  
`INTERSECT`는 첫 번째 쿼리와 두 번째 쿼리의 결과에 모두 존재하는 행만 반환합니다.  
`EXCEPT`는 두 번째 쿼리에서 찾은 행을 제외한 첫 번째 쿼리의 결과 행을 반환합니다.  
`ALL`은 동일한 행이라 하더라도 모든 행을 포함시킵니다.  
`DISTINCT`는 결합된 결과 집합에 고유한 행만 포함시킵니다.

**[ ORDER BY expression [ ASC \$1 DESC ] [ NULLS FIRST \$1 NULLS LAST] [, ...] ]**  
하나 이상의 출력 `expression`으로 결과 집합을 정렬합니다.  
절에 여러 식이 포함되어 있으면 결과 집합은 첫 번째 `expression`에 따라 정렬됩니다. 그리고 첫 번째 식에서 일치하는 값이 있는 행에 두 번째 `expression`이 적용되고, 세 번째도 동일하게 적용됩니다.  
각 `expression`은 `SELECT`의 출력 열을 지정하거나 위치별로 출력 열의 서수를 1부터 지정할 수 있습니다.  
`ORDER BY`는 `GROUP BY` 또는 `HAVING` 절 이후 마지막 단계로 평가됩니다. `ASC` 및 `DESC`는 결과를 오름차순이나 내림차순으로 정렬하도록 결정합니다. 기본적인 정렬 순서는 오름차순입니다(`ASC`). 오름차순 또는 내림차순 정렬 순서와 상관없이 기본 null 순서는 `NULLS LAST`입니다.

**[ OFFSET count [ ROW \$1 ROWS ] ]**  
`OFFSET` 절을 사용하여 결과 집합에서 여러 개의 선행 행을 삭제합니다. `ORDER BY` 절이 있는 경우 `OFFSET` 절은 정렬된 결과 집합에 대해 평가되며, 건너뛴 행이 삭제된 후에도 집합이 정렬된 상태로 유지됩니다. 쿼리에 `ORDER BY` 절이 없는 경우 삭제되는 행은 임의로 선택됩니다. `OFFSET`에 의해 지정된 수가 결과 집합의 크기와 같거나 더 크면 최종 결과는 비어 있습니다.

**LIMIT [ count \$1 ALL ]**  
결과 집합의 행 수를 `count`로 제한합니다. `LIMIT ALL`은 `LIMIT` 절 생략과 동일합니다. 쿼리에 `ORDER BY` 절이 없는 경우 결과는 임의입니다.

**TABLESAMPLE [ BERNOULLI \$1 SYSTEM ] (백분율)**  
샘플링 방법을 기반으로 테이블에서 행을 선택하는 선택적 연산자입니다.  
 `BERNOULLI`는 `percentage`의 확률로 테이블 샘플에 포함할 각 행을 선택합니다. 테이블의 모든 물리적 블록이 스캔되고 샘플 `percentage`와 실행 시간에 계산된 임의 값 사이의 비교를 기반으로 특정 행을 건너뜁니다.  
`SYSTEM`을 사용하면 테이블이 데이터의 논리적 세그먼트로 나뉘고 이 세분 수준에서 테이블이 샘플링됩니다.  
특정 세그먼트의 모든 행이 선택되거나 샘플 `percentage`와(과) 실행 시간에 계산된 임의 값 사이의 비교 결과에 따라 세그먼트를 건너뜁니다. `SYSTEM` 샘플링은 커넥터에 따라 다릅니다. 이 메서드는 독립적인 샘플링 확률을 보장하지 않습니다.

**[ UNNEST (array\$1or\$1map) [WITH ORDINALITY] ]**  
배열 또는 맵을 관계로 확장합니다. 배열은 하나의 열로 확장됩니다. 맵은 두 개의 열(*키*, *값*)로 확장됩니다.  
복수의 인수로 `UNNEST`를 사용할 수 있습니다. 이 경우 가장 큰 카디널리티 인수와 동일한 개수의 행이 있는 여러 열로 확장됩니다.  
다른 열은 null로 채워집니다.  
`WITH ORDINALITY` 절은 끝에 순서 열을 추가합니다.  
 `UNNEST`는 일반적으로 `JOIN`과 함께 사용되며 `JOIN` 왼쪽의 관계에서 열을 참조할 수 있습니다.

## Amazon S3의 소스 데이터에 대한 파일 위치 가져오기
<a name="select-path"></a>

테이블 행의 데이터에 대한 Amazon S3 파일 위치를 보려면 다음 예시처럼 `SELECT` 쿼리에 `"$path"`를 사용할 수 있습니다.

```
SELECT "$path" FROM "my_database"."my_table" WHERE year=2019;
```

이 쿼리는 다음과 같은 결과를 반환합니다.

```
s3://amzn-s3-demo-bucket/datasets_mytable/year=2019/data_file1.json
```

테이블의 데이터에 대한 S3 파일 이름 경로를 정렬된 고유 목록으로 반환하려면 다음 예시와 같이 `SELECT DISTINCT` 및 `ORDER BY`를 사용합니다.

```
SELECT DISTINCT "$path" AS data_source_file
FROM sampledb.elb_logs
ORDER By data_source_file ASC
```

경로가 없는 파일 이름만 반환하려면 다음 예시와 같이 `regexp_extract` 함수에 `"$path"`를 파라미터로 전달합니다.

```
SELECT DISTINCT regexp_extract("$path", '[^/]+$') AS data_source_file
FROM sampledb.elb_logs
ORDER By data_source_file ASC
```

특정 파일의 데이터를 반환하려면 다음 예시와 같이 `WHERE` 절에 파일을 지정합니다.

```
SELECT *,"$path" FROM my_database.my_table WHERE "$path" = 's3://amzn-s3-demo-bucket/my_table/my_partition/file-01.csv'
```

자세한 내용과 예시는 지식 센터 문서 [Athena 테이블의 행에 대한 Amazon S3 원본 파일을 확인하려면 어떻게 해야 합니까?](https://aws.amazon.com/premiumsupport/knowledge-center/find-s3-source-file-athena-table-row/)를 참조하세요.

**참고**  
Athena에서는 Hive 또는 Iceberg의 숨겨진 메타데이터 열 `$bucket`, `$file_modified_time`, `$file_size` 및 `$partition`을 보기에서 지원하지 않습니다.

## 작은따옴표의 이스케이프 처리
<a name="select-escaping"></a>

 작은따옴표를 이스케이프 처리하려면 다음 예제와 같이 작은따옴표 앞에 다른 작은따옴표를 추가합니다. 이를 큰따옴표와 혼동하지 마십시오.

```
Select 'O''Reilly'
```

**결과**  
`O'Reilly`

## 추가 리소스
<a name="select-additional-resources"></a>

Athena에서 `SELECT` 문 사용에 관한 자세한 내용은 다음 리소스를 참조하세요.


| 이에 대한 자세한 내용은 | 다음을 참조: | 
| --- | --- | 
| Athena에서 쿼리 실행 | [Amazon Athena에서 SQL 쿼리 실행](querying-athena-tables.md) | 
| SELECT를 사용해 테이블 생성 | [쿼리 결과에서 테이블 생성(CTAS)](ctas.md) | 
| SELECT 쿼리의 데이터를 다른 테이블에 삽입 | [INSERT INTO](insert-into.md) | 
| SELECT 문에서 내장 함수 사용  | [Amazon Athena의 함수](functions.md) | 
| SELECT 문에서 사용자가 정의한 함수 사용 | [사용자 정의 함수를 사용한 쿼리](querying-udf.md) | 
| 데이터 카탈로그 메타데이터 쿼리 | [AWS Glue Data Catalog 쿼리](querying-glue-catalog.md) | 

# 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')
```

# VALUES
<a name="values-statement"></a>

리터럴 인라인 테이블을 생성합니다. 테이블은 익명입니다. 또는 `AS` 절을 사용하여 테이블 이름, 열 이름을 각각 지정하거나 모두 지정할 수 있습니다.

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

```
VALUES row [, ...]
```

## 파라미터
<a name="values-statement-parameters"></a>

**행**  
`row` 파라미터는 단일 표현식 또는 `( column_expression [, ...] )`일 수 있습니다.

## 예시
<a name="values-statement-examples"></a>

열 하나와 행 세 개가 있는 테이블을 반환합니다.

```
VALUES 1, 2, 3
```

열 2개와 행 3개가 있는 테이블을 반환합니다.

```
VALUES
    (1, 'a'),
    (2, 'b'),
    (3, 'c')
```

`id` 및 `name` 열이 있는 테이블을 반환합니다.

```
SELECT * FROM (
    VALUES
        (1, 'a'),
        (2, 'b'),
        (3, 'c')
) AS t (id, name)
```

`id` 및 `name` 열이 있는 `customers` 이름의 테이블을 생성합니다.

```
CREATE TABLE customers AS
SELECT * FROM (
    VALUES
        (1, 'a'),
        (2, 'b'),
        (3, 'c')
) AS t (id, name)
```

## 다음 사항도 참조하세요.
<a name="values-statement-see-also"></a>

[INSERT INTO...VALUES](insert-into.md#insert-into-values)

# DELETE
<a name="delete-statement"></a>

Apache Iceberg 테이블의 행을 삭제합니다. `DELETE`는 트랜잭션이며 Apache Iceberg 테이블에서만 지원됩니다.

## 시놉시스
<a name="delete-statement-synopsis"></a>

Iceberg 테이블에서 행을 삭제하려면 다음 구문을 사용합니다.

```
DELETE FROM [db_name.]table_name [WHERE predicate]
```

자세한 내용과 예제는 [Iceberg 테이블 데이터 업데이트](querying-iceberg-updating-iceberg-table-data.md)의 `DELETE` 단원을 참조하세요.

# UPDATE
<a name="update-statement"></a>

Apache Iceberg 테이블의 행을 업데이트합니다. `UPDATE`는 트랜잭션이며 Apache Iceberg 테이블에서만 지원됩니다. 문은 기존 행에서만 작동하며 행을 삽입하거나 추가하는 데 사용할 수 없습니다.

## 시놉시스
<a name="update-statement-synopsis"></a>

Iceberg 테이블의 행을 업데이트하려면 다음 구문을 사용합니다.

```
UPDATE [db_name.]table_name SET xx=yy[,...] [WHERE predicate]
```

자세한 내용과 예제는 [Iceberg 테이블 데이터 업데이트](querying-iceberg-updating-iceberg-table-data.md)의 `UPDATE` 단원을 참조하세요.

# MERGE INTO
<a name="merge-into-statement"></a>

Apache Iceberg 테이블에 행을 조건부로 업데이트, 삭제 또는 삽입합니다. 단일 명령문으로 업데이트, 삭제 및 삽입 작업을 결합할 수 있습니다.

**참고**  
`MERGE INTO`은 트랜잭션이며 Athena 엔진 버전 3의 Apache Iceberg 테이블에 대해서만 지원됩니다.

## 시놉시스
<a name="merge-into-statement-synopsis"></a>

Iceberg 테이블에서 행을 조건부로 업데이트, 삭제 또는 삽입하려면 다음 구문을 사용합니다.

```
MERGE INTO target_table [ [ AS ]  target_alias ]
USING { source_table | query } [ [ AS ] source_alias ]
ON search_condition
when_clause [...]
```

*when\$1clause*는 다음 중 하나입니다.

```
WHEN MATCHED [ AND condition ]
    THEN DELETE
```

```
WHEN MATCHED [ AND condition ]
    THEN UPDATE SET ( column = expression [, ...] )
```

```
WHEN NOT MATCHED [ AND condition ]
    THEN INSERT (column_name[, column_name ...]) VALUES (expression, ...)
```

`MERGE`는 서로 다른 `MATCHED` 조건을 가진 임의 개수의 `WHEN` 절을 지원합니다. 조건 절은 `MATCHED` 상태와 일치 조건에 따라 선택된 첫 번째 `WHEN` 절에서 `DELETE`, `UPDATE` 또는 `INSERT` 작업을 실행합니다.

각 소스 행에 대해 `WHEN` 절이 순서대로 처리됩니다. 일치하는 첫 번째 `WHEN` 절만 실행됩니다. 후속 절은 무시됩니다. 하나의 대상 테이블 행이 둘 이상의 소스 행과 일치할 경우 사용자 오류가 발생합니다.

소스 행이 `WHEN` 절과 일치하지 않고 `WHEN NOT MATCHED` 절이 없는 경우 해당 소스 행은 무시됩니다.

`UPDATE` 작업이 있는 `WHEN` 절에서 열 값 표현식은 대상 또는 소스의 모든 필드를 참조할 수 있습니다. `NOT MATCHED`의 경우 `INSERT` 표현식은 소스의 모든 필드를 참조할 수 있습니다.

**예**  
다음 예제에서는 첫 번째 테이블에 행이 없는 경우 두 번째 테이블의 행을 첫 번째 테이블에 병합합니다. `VALUES` 절에 나열된 열에 소스 테이블 별칭이 접두사로 사용되어야 합니다. `INSERT` 절에 나열된 대상 열에는 이 접두사를 사용해서는 *안 됩니다*.

```
MERGE INTO iceberg_table_sample as ice1
USING iceberg2_table_sample as ice2
ON ice1.col1 = ice2.col1
WHEN NOT MATCHED 
THEN INSERT (col1)
      VALUES (ice2.col1)
```

더 많은 `MERGE INTO` 예제는 [Iceberg 테이블 데이터 업데이트](querying-iceberg-updating-iceberg-table-data.md) 섹션을 참조하세요.

# OPTIMIZE
<a name="optimize-statement"></a>

연결된 삭제 파일의 크기와 수에 따라 데이터 파일을 보다 최적화된 레이아웃으로 재작성하여 Apache Iceberg 테이블의 행을 최적화합니다.

**참고**  
`OPTIMIZE`는 트랜잭션이며 Apache Iceberg 테이블에 대해서만 지원됩니다.

## 구문
<a name="optimize-statement-syntax"></a>

다음 구문 요약은 Iceberg 테이블의 데이터 레이아웃을 최적화하는 방법을 보여줍니다.

```
OPTIMIZE [db_name.]table_name REWRITE DATA USING BIN_PACK
  [WHERE predicate]
```

**참고**  
`WHERE` 절 *조건자*에는 파티션 열만 사용할 수 있습니다. 파티션되지 않은 열을 지정하면 쿼리가 실패합니다.

압축 작업은 재작성 프로세스 중에 스캔된 데이터의 양에 따라 요금이 부과됩니다. `REWRITE DATA` 작업은 술어를 사용하여 일치하는 행이 포함된 파일을 선택합니다. 파일의 행이 술어와 일치하는 경우 최적화를 위해 파일이 선택됩니다. 따라서 압축 작업의 영향을 받는 파일 수를 제어하려면 `WHERE` 절을 지정합니다.

## 압축 속성 구성
<a name="optimize-statement-configuring-compaction-properties"></a>

압축을 위해 선택할 파일의 크기와 압축 후 결과 파일 크기를 제어하려면 테이블 속성 파라미터를 사용할 수 있습니다. [ALTER TABLE SET TBLPROPERTIES](querying-iceberg-alter-table-set-properties.md) 명령을 사용하여 다음 [테이블 속성](querying-iceberg-creating-tables.md#querying-iceberg-table-properties)을 구성할 수 있습니다.

## 추가 리소스
<a name="optimize-statement-additional-resources"></a>

[Iceberg 테이블 최적화](querying-iceberg-data-optimization.md)

# VACUUM
<a name="vacuum-statement"></a>

`VACUUM`문은 [스냅샷 만료](https://iceberg.apache.org/docs/latest/spark-procedures/#expire_snapshots) 및 [분리된 파일 제거](https://iceberg.apache.org/docs/latest/spark-procedures/#remove_orphan_files)를 수행하여 Apache Iceberg 테이블에서 테이블 유지 관리를 수행합니다.

**참고**  
`VACUUM`은 트랜잭션이며 Athena 엔진 버전 3의 Apache Iceberg 테이블에 대해서만 지원됩니다.

`VACUUM` 명령문은 스토리지 사용량을 줄여 Iceberg 테이블을 최적화합니다. `VACUUM` 사용에 관한 자세한 내용은 [Iceberg 테이블 최적화](querying-iceberg-data-optimization.md) 부분을 참조하세요. 단, `VACUUM` 문은 Amazon S3에 API를 직접적으로 호출하므로 Amazon S3에 대한 관련 요청에 요금이 부과됩니다.

**주의**  
스냅샷 만료 작업을 실행하면 더 이상 만료된 스냅샷으로 이동할 수 없습니다.

## 시놉시스
<a name="vacuum-statement-synopsis"></a>

Iceberg 테이블에 더 이상 필요하지 않은 데이터 파일을 제거하려면 다음 구문을 사용합니다.

```
VACUUM [database_name.]target_table
```
+ `VACUUM`은 Iceberg 데이터가 Amazon S3 버킷이 아닌 Amazon S3 폴더에 있을 것으로 예상합니다. 예를 들어 Iceberg 데이터가 `s3://amzn-s3-demo-bucket/myicebergfolder/`가 아닌 `s3://amzn-s3-demo-bucket`/에 있는 경우 `VACUUM` 문이 실패하고 GENERIC\$1INTERNAL\$1ERROR: Path missing in file system location: `s3://amzn-s3-demo-bucket`라는 오류 메시지가 표시됩니다.
+ `VACUUM`에서 데이터 파일을 삭제할 수 있으려면 쿼리 실행 역할에 Iceberg 테이블, 메타데이터, 스냅샷 및 데이터 파일이 있는 버킷에 대한 `s3:DeleteObject` 권한이 있어야 합니다. 권한이 없는 경우 `VACUUM` 쿼리는 성공하지만 파일은 삭제되지 않습니다.
+ 이름이 밑줄로 시작하는 테이블(예: `_mytable`)에서 `VACUUM`을 실행하려면 다음 예제와 같이 테이블 이름을 백틱으로 묶습니다. 테이블 이름 앞에 데이터베이스 이름을 붙이는 경우 데이터베이스 이름을 백틱으로 묶지 마세요. 큰따옴표는 백틱 대신 사용할 수 없다는 점에 유의하세요.

  이 동작은 특히 `VACUUM`에 발생합니다. `CREATE` 및 `INSERT INTO` 문에서는 밑줄로 시작하는 테이블 이름에 백틱을 사용하지 않아도 됩니다.

  ```
  VACUUM `_mytable`
  VACUUM my_database.`_mytable`
  ```

## 작업 수행됨
<a name="vacuum-statement-operations-performed"></a>

`VACUUM`은 다음 작업을 수행합니다.
+ `vacuum_max_snapshot_age_seconds` 테이블 속성에 지정된 시간보다 오래된 스냅샷을 제거합니다. 기본적으로 이 속성은 432000초(5일)로 설정됩니다.
+ 보존 기간 내에 있지 않고 `vacuum_min_snapshots_to_keep` 테이블 속성에 지정된 수를 초과하는 스냅샷을 제거합니다. 기본 값은 1입니다.

  `CREATE TABLE` 문에서 이러한 테이블 속성을 지정할 수 있습니다. 테이블이 생성된 이후에 [ALTER TABLE SET TBLPROPERTIES](querying-iceberg-alter-table-set-properties.md) 문을 사용하여 테이블을 업데이트할 수 있습니다.
+ 스냅샷 제거로 인해 연결할 수 없는 메타데이터 및 데이터 파일을 제거합니다. `vacuum_max_metadata_files_to_keep` 테이블 속성을 설정하여 보존할 이전 메타데이터 파일 수를 구성할 수 있습니다. 기본 값은 100입니다.
+ `vacuum_max_snapshot_age_seconds` 테이블 속성에 지정된 시간보다 오래된 분리된 파일을 제거합니다. 분리된 파일은 테이블의 데이터 디렉터리에서 테이블 상태에 포함되지 않는 파일입니다.

Athena의 Apache Iceberg 테이블 생성 및 관리에 대한 자세한 내용은 [Iceberg 테이블 생성](querying-iceberg-creating-tables.md) 및 [Iceberg 테이블 관리](querying-iceberg-managing-tables.md) 단원을 참조하세요.

# Athena에서 EXPLAIN 및 EXPLAIN ANALYZE 사용
<a name="athena-explain-statement"></a>

`EXPLAIN` 문은 지정된 SQL 문의 논리적 또는 분산 실행 계획을 보여주거나 SQL 문의 유효성을 검사합니다. 결과를 텍스트 형식 또는 데이터 형식으로 출력하여 그래프로 렌더링할 수 있습니다.

**참고**  
`EXPLAIN` 구문을 사용하지 않고도 쿼리에 대한 논리적 계획 및 분산된 계획의 그래픽 표현을 Athena 콘솔에서 볼 수 있습니다. 자세한 내용은 [SQL 쿼리에 대한 실행 계획 보기](query-plans.md) 섹션을 참조하세요.

`EXPLAIN ANALYZE` 문은 지정된 SQL 문의 분산 실행 계획과 SQL 쿼리의 각 작업 계산 비용을 모두 표시합니다. 결과를 텍스트 또는 JSON 형식으로 출력할 수 있습니다.

## 고려 사항 및 제한 사항
<a name="athena-explain-statement-considerations-and-limitations"></a>

Athena의`EXPLAIN` 및 `EXPLAIN ANALYZE` 문에는 다음과 같은 제한이 있습니다.
+ `EXPLAIN` 쿼리는 어떠한 데이터도 스캔하지 않으므로 Athena는 이에 대해 과금하지 않습니다. 그러나 `EXPLAIN` 쿼리는 AWS Glue를 호출하여 테이블 메타데이터를 검색하기 때문에 호출이 [Glue의 프리 티어 한도](https://aws.amazon.com/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Categories=categories%23analytics&all-free-tier.q=glue&all-free-tier.q_operator=AND)를 초과할 경우 Glue에서 요금이 발생할 수 있습니다.
+ `EXPLAIN ANALYZE` 쿼리가 실행되면 스캔 데이터를 수행하고 Athena가 스캔한 데이터 양에 대해 요금을 청구하기 때문입니다.
+ Lake Formation에 정의된 행 또는 셀 필터링 정보와 쿼리 통계 정보는 `EXPLAIN` 및 `EXPLAIN ANALYZE`의 출력에 표시되지 않습니다.

## EXPLAIN 구문
<a name="athena-explain-statement-syntax-athena-engine-version-2"></a>

```
EXPLAIN [ ( option [, ...]) ] statement
```

*옵션*은 다음 중 하나일 수 있습니다.

```
FORMAT { TEXT | GRAPHVIZ | JSON }
TYPE { LOGICAL | DISTRIBUTED | VALIDATE | IO }
```

`FORMAT` 옵션이 지정되지 않은 경우 출력은 기본적으로 `TEXT` 형식입니다. `IO` 유형은 쿼리에서 읽는 테이블 및 스키마에 대한 정보를 제공합니다.

## EXPLAIN ANALYZE 구문
<a name="athena-explain-analyze-statement"></a>

`EXPLAIN`에 포함된 출력 외에도 `EXPLAIN ANALYZE` 출력에는 CPU 사용량, 입력 행 수 및 출력 행 수와 같은 지정된 쿼리에 대한 런타임 통계도 포함됩니다.

```
EXPLAIN ANALYZE [ ( option [, ...]) ] statement
```

*옵션*은 다음 중 하나일 수 있습니다.

```
FORMAT { TEXT | JSON }
```

`FORMAT` 옵션이 지정되지 않은 경우 출력은 기본적으로 `TEXT` 형식입니다. `EXPLAIN ANALYZE`에 대한 모든 쿼리는 `DISTRIBUTED`이며, `TYPE` 옵션은 `EXPLAIN ANALYZE`에 사용할 수 없기 때문입니다.

*statement*는 다음 중 하나일 수 있습니다.

```
SELECT
CREATE TABLE AS SELECT
INSERT
UNLOAD
```

## EXPLAIN 예제
<a name="athena-explain-statement-examples"></a>

`EXPLAIN`에 대한 다음 예는 더 간단한 예에서 더 복잡한 예로 진행됩니다.

### 예제 1: EXPLAIN 문을 사용하여 텍스트 형식의 쿼리 계획을 표시
<a name="athena-explain-statement-example-text-query-plan"></a>

다음 예에서 `EXPLAIN`은 Elastic Load Balancing 로그 기반 `SELECT` 쿼리에 대한 실행 계획을 보여줍니다. 형식은 기본적으로 텍스트 출력입니다.

```
EXPLAIN 
SELECT 
   request_timestamp, 
   elb_name, 
   request_ip 
FROM sampledb.elb_logs;
```

#### 결과
<a name="athena-explain-statement-example-text-query-plan-results"></a>

```
- Output[request_timestamp, elb_name, request_ip] => [[request_timestamp, elb_name, request_ip]]
    - RemoteExchange[GATHER] => [[request_timestamp, elb_name, request_ip]]
        - TableScan[awsdatacatalog:HiveTableHandle{schemaName=sampledb, tableName=elb_logs, 
analyzePartitionValues=Optional.empty}] => [[request_timestamp, elb_name, request_ip]]
                LAYOUT: sampledb.elb_logs
                request_ip := request_ip:string:2:REGULAR
                request_timestamp := request_timestamp:string:0:REGULAR
                elb_name := elb_name:string:1:REGULAR
```

### 예제 2: EXPLAIN 문을 사용하여 쿼리 계획을 그래프로 작성
<a name="athena-explain-statement-example-graph-a-query-plan"></a>

Athena 콘솔을 사용하여 쿼리 계획을 그래프로 작성할 수 있습니다. Athena 쿼리 편집기에 다음과 같이 `SELECT` 문을 입력한 다음 **EXPLAIN**을 선택합니다.

```
SELECT 
      c.c_custkey,
      o.o_orderkey,
      o.o_orderstatus
   FROM tpch100.customer c 
   JOIN tpch100.orders o 
       ON c.c_custkey = o.o_custkey
```

Athena 쿼리 편집기의 **Explain** 페이지가 열리고 쿼리에 대한 분산 계획과 논리적 계획이 표시됩니다. 다음 그래프는 예제의 논리적 계획을 보여줍니다.

![\[Athena 쿼리 편집기에서 렌더링한 쿼리 계획의 그래프.\]](http://docs.aws.amazon.com/ko_kr/athena/latest/ug/images/athena-explain-statement-tpch.png)


**중요**  
현재 일부 파티션 필터는 Athena에서 쿼리에 적용하더라도 중첩 연산자 트리 그래프에 표시되지 않을 수도 있습니다. 이러한 필터의 효과를 확인하려면 쿼리에서 `EXPLAIN` 또는 `EXPLAIN ANALYZE`를 실행하고 결과를 확인합니다.

Athena 콘솔에서 쿼리 계획 그래프 작성 기능 사용에 대한 자세한 내용은 [SQL 쿼리에 대한 실행 계획 보기](query-plans.md) 단원을 참조하세요.

### 예제 3: EXPLAIN 문을 사용하여 파티션 정리 확인
<a name="athena-explain-statement-example-verify-partition-pruning"></a>

분할된 테이블을 쿼리할 때 분할된 키에 필터링 조건자를 사용하면 쿼리 엔진은 조건자를 분할된 키에 적용해 읽는 데이터의 양을 줄입니다.

다음 예제에서는 `EXPLAIN` 쿼리를 사용하여 분할된 테이블에 대한 `SELECT` 쿼리의 파티션 정리를 확인합니다. 먼저 `CREATE TABLE` 문은 `tpch100.orders_partitioned` 테이블을 생성합니다. 테이블은 `o_orderdate` 열에서 분할됩니다.

```
CREATE TABLE `tpch100.orders_partitioned`(
  `o_orderkey` int, 
  `o_custkey` int, 
  `o_orderstatus` string, 
  `o_totalprice` double, 
  `o_orderpriority` string, 
  `o_clerk` string, 
  `o_shippriority` int, 
  `o_comment` string)
PARTITIONED BY ( 
  `o_orderdate` 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/<your_directory_path>/'
```

`SHOW PARTITIONS` 명령으로 표시된 것처럼 `tpch100.orders_partitioned` 테이블에는 `o_orderdate`에 여러 개의 파티션이 있습니다.

```
SHOW PARTITIONS tpch100.orders_partitioned;

o_orderdate=1994
o_orderdate=2015
o_orderdate=1998
o_orderdate=1995
o_orderdate=1993
o_orderdate=1997
o_orderdate=1992
o_orderdate=1996
```

다음 `EXPLAIN` 쿼리는 지정된 `SELECT` 문의 파티션 정리를 확인합니다.

```
EXPLAIN 
SELECT 
   o_orderkey, 
   o_custkey, 
   o_orderdate 
FROM tpch100.orders_partitioned
WHERE o_orderdate = '1995'
```

#### 결과
<a name="athena-explain-statement-example-verify-partition-pruning-results"></a>

```
Query Plan
- Output[o_orderkey, o_custkey, o_orderdate] => [[o_orderkey, o_custkey, o_orderdate]]
    - RemoteExchange[GATHER] => [[o_orderkey, o_custkey, o_orderdate]]
        - TableScan[awsdatacatalog:HiveTableHandle{schemaName=tpch100, tableName=orders_partitioned, 
analyzePartitionValues=Optional.empty}] => [[o_orderkey, o_custkey, o_orderdate]]
                LAYOUT: tpch100.orders_partitioned
                o_orderdate := o_orderdate:string:-1:PARTITION_KEY
                    :: [[1995]]
                o_custkey := o_custkey:int:1:REGULAR
                o_orderkey := o_orderkey:int:0:REGULAR
```

결과에서 굵은 텍스트는 `o_orderdate = '1995'` 조건자가 `PARTITION_KEY`에 적용되었음을 나타냅니다.

### 예제 4: EXPLAIN 쿼리를 사용하여 조인 순서 및 조인 유형 확인
<a name="athena-explain-statement-example-check-join-order-and-type"></a>

다음 `EXPLAIN` 쿼리는 `SELECT` 문의 조인 순서 및 조인 유형을 확인합니다. 이와 같은 쿼리를 사용하면 쿼리 메모리 사용량을 검사하여 `EXCEEDED_LOCAL_MEMORY_LIMIT` 오류가 발생할 확률을 줄일 수 있습니다.

```
EXPLAIN (TYPE DISTRIBUTED)
   SELECT 
      c.c_custkey, 
      o.o_orderkey,
      o.o_orderstatus
   FROM tpch100.customer c 
   JOIN tpch100.orders o 
       ON c.c_custkey = o.o_custkey 
   WHERE c.c_custkey = 123
```

#### 결과
<a name="athena-explain-statement-example-check-join-order-and-type-results"></a>

```
Query Plan
Fragment 0 [SINGLE]
    Output layout: [c_custkey, o_orderkey, o_orderstatus]
    Output partitioning: SINGLE []
    Stage Execution Strategy: UNGROUPED_EXECUTION
    - Output[c_custkey, o_orderkey, o_orderstatus] => [[c_custkey, o_orderkey, o_orderstatus]]
        - RemoteSource[1] => [[c_custkey, o_orderstatus, o_orderkey]]

Fragment 1 [SOURCE]
    Output layout: [c_custkey, o_orderstatus, o_orderkey]
    Output partitioning: SINGLE []
    Stage Execution Strategy: UNGROUPED_EXECUTION
    - CrossJoin => [[c_custkey, o_orderstatus, o_orderkey]]
            Distribution: REPLICATED
        - ScanFilter[table = awsdatacatalog:HiveTableHandle{schemaName=tpch100, 
tableName=customer, analyzePartitionValues=Optional.empty}, grouped = false, 
filterPredicate = ("c_custkey" = 123)] => [[c_custkey]]
                LAYOUT: tpch100.customer
                c_custkey := c_custkey:int:0:REGULAR
        - LocalExchange[SINGLE] () => [[o_orderstatus, o_orderkey]]
            - RemoteSource[2] => [[o_orderstatus, o_orderkey]]

Fragment 2 [SOURCE]
    Output layout: [o_orderstatus, o_orderkey]
    Output partitioning: BROADCAST []
    Stage Execution Strategy: UNGROUPED_EXECUTION
    - ScanFilterProject[table = awsdatacatalog:HiveTableHandle{schemaName=tpch100, 
tableName=orders, analyzePartitionValues=Optional.empty}, grouped = false, 
filterPredicate = ("o_custkey" = 123)] => [[o_orderstatus, o_orderkey]]
            LAYOUT: tpch100.orders
            o_orderstatus := o_orderstatus:string:2:REGULAR
            o_custkey := o_custkey:int:1:REGULAR
            o_orderkey := o_orderkey:int:0:REGULAR
```

예제 쿼리는 성능 향상을 위해 크로스 조인으로 최적화되었습니다. 결과는 `tpch100.orders`가 `BROADCAST` 배포 유형으로 배포될 예정임을 보여줍니다. 이는 `tpch100.orders` 테이블이 조인 작업을 수행하는 모든 노드에 배포될 것임을 의미합니다. `BROADCAST` 배포 유형은 `tpch100.orders` 테이블의 모든 필터링된 결과가 조인 작업을 수행하는 각 노드의 메모리에 부합할 것을 요구합니다.

그러나 `tpch100.customer` 테이블은 `tpch100.orders`보다 작습니다. `tpch100.customer`는 더 적은 메모리를 필요로 하므로 쿼리를 `tpch100.orders` 대신에 `BROADCAST tpch100.customer`에 다시 작성할 수 있습니다. 이렇게 하면 쿼리가 `EXCEEDED_LOCAL_MEMORY_LIMIT` 오류를 수신할 가능성이 낮아집니다. 이 전략은 다음 사항을 가정합니다.
+ `tpch100.customer.c_custkey`가 `tpch100.customer` 테이블에서 고유합니다.
+ `tpch100.customer`와 `tpch100.orders` 사이에 일대다 매핑 관계가 있습니다.

다음 예제에서는 다시 작성된 쿼리를 보여줍니다.

```
SELECT 
    c.c_custkey,
    o.o_orderkey,
    o.o_orderstatus
FROM tpch100.orders o
JOIN tpch100.customer c -- the filtered results of tpch100.customer are distributed to all nodes.
    ON c.c_custkey = o.o_custkey 
WHERE c.c_custkey = 123
```

### 예제 5: EXPLAIN 쿼리를 사용하여 영향이 없는 조건자 제거
<a name="athena-explain-statement-example-remove-unneeded-predicates"></a>

`EXPLAIN` 쿼리를 사용하여 필터링 조건자의 영향을 확인할 수 있습니다. 다음 예제와 같이 결과를 사용하여 영향이 없는 조건자를 제거할 수 있습니다.

```
EXPLAIN
   SELECT 
      c.c_name
   FROM tpch100.customer c
   WHERE c.c_custkey = CAST(RANDOM() * 1000 AS INT)
   AND c.c_custkey BETWEEN 1000 AND 2000
   AND c.c_custkey = 1500
```

#### 결과
<a name="athena-explain-statement-example-remove-unneeded-predicates-results"></a>

```
Query Plan
- Output[c_name] => [[c_name]]
    - RemoteExchange[GATHER] => [[c_name]]
        - ScanFilterProject[table = 
awsdatacatalog:HiveTableHandle{schemaName=tpch100, 
tableName=customer, analyzePartitionValues=Optional.empty}, 
filterPredicate = (("c_custkey" = 1500) AND ("c_custkey" = 
CAST(("random"() * 1E3) AS int)))] => [[c_name]]
                LAYOUT: tpch100.customer
                c_custkey := c_custkey:int:0:REGULAR
                c_name := c_name:string:1:REGULAR
```

결과의 `filterPredicate`는 옵티마이저가 원래 세 개인 조건자를 두 개의 조건자로 병합하고 애플리케이션의 순서를 변경했음을 보여줍니다.

```
filterPredicate = (("c_custkey" = 1500) AND ("c_custkey" = CAST(("random"() * 1E3) AS int)))
```

결과에 따르면 `AND c.c_custkey BETWEEN 1000 AND 2000` 조건자는 아무런 영향이 없으므로 쿼리 결과의 변화 없이 이 조건자를 제거할 수 있습니다.

`EXPLAIN` 쿼리의 결과에 사용된 용어에 관한 자세한 내용은 [Athena EXPLAIN 문 결과 이해](athena-explain-statement-understanding.md) 단원을 참조하세요.

## EXPLAIN ANALYZE 예제
<a name="athena-explain-analyze-examples"></a>

다음 예에서는 `EXPLAIN ANALYZE` 쿼리 및 출력 예를 보여줍니다.

### 예제 1: EXPLAIN ANALYZE를 사용하여 텍스트 형식으로 쿼리 계획 및 계산 비용 표시
<a name="athena-explain-analyze-example-cflogs-text"></a>

다음 예에서 `EXPLAIN ANALYZE`는 CloudFront 로그의 `SELECT` 쿼리에 대한 실행 계획 및 계산 비용을 보여줍니다. 형식은 기본적으로 텍스트 출력입니다.

```
EXPLAIN ANALYZE SELECT FROM cloudfront_logs LIMIT 10
```

#### 결과
<a name="athena-explain-analyze-example-cflogs-text-results"></a>

```
 Fragment 1
     CPU: 24.60ms, Input: 10 rows (1.48kB); per task: std.dev.: 0.00, Output: 10 rows (1.48kB)
     Output layout: [date, time, location, bytes, requestip, method, host, uri, status, referrer,\
       os, browser, browserversion]
Limit[10] => [[date, time, location, bytes, requestip, method, host, uri, status, referrer, os,\
  browser, browserversion]]
             CPU: 1.00ms (0.03%), Output: 10 rows (1.48kB)
             Input avg.: 10.00 rows, Input std.dev.: 0.00%
LocalExchange[SINGLE] () => [[date, time, location, bytes, requestip, method, host, uri, status, referrer, os,\
 browser, browserversion]]
                 CPU: 0.00ns (0.00%), Output: 10 rows (1.48kB)
                 Input avg.: 0.63 rows, Input std.dev.: 387.30%
RemoteSource[2] => [[date, time, location, bytes, requestip, method, host, uri, status, referrer, os,\
  browser, browserversion]]
                     CPU: 1.00ms (0.03%), Output: 10 rows (1.48kB)
                     Input avg.: 0.63 rows, Input std.dev.: 387.30%

 Fragment 2
     CPU: 3.83s, Input: 998 rows (147.21kB); per task: std.dev.: 0.00, Output: 20 rows (2.95kB)
     Output layout: [date, time, location, bytes, requestip, method, host, uri, status, referrer, os,\
       browser, browserversion]
LimitPartial[10] => [[date, time, location, bytes, requestip, method, host, uri, status, referrer, os,\
  browser, browserversion]]
             CPU: 5.00ms (0.13%), Output: 20 rows (2.95kB)
             Input avg.: 166.33 rows, Input std.dev.: 141.42%
TableScan[awsdatacatalog:HiveTableHandle{schemaName=default, tableName=cloudfront_logs,\
  analyzePartitionValues=Optional.empty}, 
grouped = false] => [[date, time, location, bytes, requestip, method, host, uri, st
                 CPU: 3.82s (99.82%), Output: 998 rows (147.21kB)
                 Input avg.: 166.33 rows, Input std.dev.: 141.42%
                 LAYOUT: default.cloudfront_logs
                 date := date:date:0:REGULAR
                 referrer := referrer:string:9:REGULAR
                 os := os:string:10:REGULAR
                 method := method:string:5:REGULAR
                 bytes := bytes:int:3:REGULAR
                 browser := browser:string:11:REGULAR
                 host := host:string:6:REGULAR
                 requestip := requestip:string:4:REGULAR
                 location := location:string:2:REGULAR
                 time := time:string:1:REGULAR
                 uri := uri:string:7:REGULAR
                 browserversion := browserversion:string:12:REGULAR
                 status := status:int:8:REGULAR
```

### 예제 2: EXPLAIN ANALYZE를 사용하여 JSON 형식으로 쿼리 계획 표시
<a name="athena-explain-analyze-example-cflogs-json"></a>

다음 예에서는 CloudFront 로그 기반 `SELECT` 쿼리에 대한 실행 계획 및 계산 비용을 보여줍니다. 이 예에서는 JSON을 출력 형식으로 지정합니다.

```
EXPLAIN ANALYZE (FORMAT JSON) SELECT * FROM cloudfront_logs LIMIT 10
```

#### 결과
<a name="athena-explain-analyze-example-cflogs-json-results"></a>

```
{ 
    "fragments": [{ 
        "id": "1", 
 
        "stageStats": { 
            "totalCpuTime": "3.31ms", 
            "inputRows": "10 rows", 
            "inputDataSize": "1514B", 
            "stdDevInputRows": "0.00", 
            "outputRows": "10 rows", 
            "outputDataSize": "1514B" 
        }, 
        "outputLayout": "date, time, location, bytes, requestip, method, host,\
           uri, status, referrer, os, browser, browserversion", 
 
        "logicalPlan": { 
            "1": [{ 
                "name": "Limit", 
                "identifier": "[10]", 
                "outputs": ["date", "time", "location", "bytes", "requestip", "method", "host",\
                  "uri", "status", "referrer", "os", "browser", "browserversion"], 
                "details": "", 
                "distributedNodeStats": { 
                    "nodeCpuTime": "0.00ns", 
                    "nodeOutputRows": 10, 
                    "nodeOutputDataSize": "1514B", 
                    "operatorInputRowsStats": [{ 
                        "nodeInputRows": 10.0, 
                        "nodeInputRowsStdDev": 0.0 
                    }] 
                }, 
                "children": [{ 
                    "name": "LocalExchange", 
                    "identifier": "[SINGLE] ()", 
                    "outputs": ["date", "time", "location", "bytes", "requestip", "method", "host",\
                      "uri", "status", "referrer", "os", "browser", "browserversion"], 
                    "details": "", 
                    "distributedNodeStats": { 
                        "nodeCpuTime": "0.00ns", 
                        "nodeOutputRows": 10, 
                        "nodeOutputDataSize": "1514B", 
                        "operatorInputRowsStats": [{ 
                            "nodeInputRows": 0.625, 
                            "nodeInputRowsStdDev": 387.2983346207417 
                        }] 
                    }, 
                    "children": [{ 
                        "name": "RemoteSource", 
                        "identifier": "[2]", 
                        "outputs": ["date", "time", "location", "bytes", "requestip", "method", "host",\
                          "uri", "status", "referrer", "os", "browser", "browserversion"], 
                        "details": "", 
                        "distributedNodeStats": { 
                            "nodeCpuTime": "0.00ns", 
                            "nodeOutputRows": 10, 
                            "nodeOutputDataSize": "1514B", 
                            "operatorInputRowsStats": [{ 
                                "nodeInputRows": 0.625, 
                                "nodeInputRowsStdDev": 387.2983346207417 
                            }] 
                        }, 
                        "children": [] 
                    }] 
                }] 
            }] 
        } 
    }, { 
        "id": "2", 
 
        "stageStats": { 
            "totalCpuTime": "1.62s", 
            "inputRows": "500 rows", 
            "inputDataSize": "75564B", 
            "stdDevInputRows": "0.00", 
            "outputRows": "10 rows", 
            "outputDataSize": "1514B" 
        }, 
        "outputLayout": "date, time, location, bytes, requestip, method, host, uri, status,\
           referrer, os, browser, browserversion", 
 
        "logicalPlan": { 
            "1": [{ 
                "name": "LimitPartial", 
                "identifier": "[10]", 
                "outputs": ["date", "time", "location", "bytes", "requestip", "method", "host", "uri",\
                  "status", "referrer", "os", "browser", "browserversion"], 
                "details": "", 
                "distributedNodeStats": { 
                    "nodeCpuTime": "0.00ns", 
                    "nodeOutputRows": 10, 
                    "nodeOutputDataSize": "1514B", 
                    "operatorInputRowsStats": [{ 
                        "nodeInputRows": 83.33333333333333, 
                        "nodeInputRowsStdDev": 223.60679774997897 
                    }] 
                }, 
                "children": [{ 
                    "name": "TableScan", 
                    "identifier": "[awsdatacatalog:HiveTableHandle{schemaName=default,\
                       tableName=cloudfront_logs, analyzePartitionValues=Optional.empty},\
                       grouped = false]", 
                    "outputs": ["date", "time", "location", "bytes", "requestip", "method", "host", "uri",\
                       "status", "referrer", "os", "browser", "browserversion"], 
                    "details": "LAYOUT: default.cloudfront_logs\ndate := date:date:0:REGULAR\nreferrer :=\
                       referrer: string:9:REGULAR\nos := os:string:10:REGULAR\nmethod := method:string:5:\
                       REGULAR\nbytes := bytes:int:3:REGULAR\nbrowser := browser:string:11:REGULAR\nhost :=\
                       host:string:6:REGULAR\nrequestip := requestip:string:4:REGULAR\nlocation :=\
                       location:string:2:REGULAR\ntime := time:string:1: REGULAR\nuri := uri:string:7:\
                       REGULAR\nbrowserversion := browserversion:string:12:REGULAR\nstatus :=\
                       status:int:8:REGULAR\n", 
                    "distributedNodeStats": { 
                        "nodeCpuTime": "1.62s", 
                        "nodeOutputRows": 500, 
                        "nodeOutputDataSize": "75564B", 
                        "operatorInputRowsStats": [{ 
                            "nodeInputRows": 83.33333333333333, 
                            "nodeInputRowsStdDev": 223.60679774997897 
                        }] 
                    }, 
                    "children": [] 
                }] 
            }] 
        } 
    }] 
}
```

## 추가 리소스
<a name="athena-explain-statement-additional-resources"></a>

자세한 내용은 다음 리소스를 참조하세요.
+  [Athena EXPLAIN 문 결과 이해](athena-explain-statement-understanding.md)
+  [SQL 쿼리에 대한 실행 계획 보기](query-plans.md)
+  [완료된 쿼리에 대한 통계 및 실행 세부 정보 보기](query-stats.md)
+ Trino [https://trino.io/docs/current/sql/explain.html](https://trino.io/docs/current/sql/explain.html) 설명서
+ Trino [https://trino.io/docs/current/sql/explain-analyze.html](https://trino.io/docs/current/sql/explain-analyze.html) 설명서
+  *AWS 빅 데이터 블로그*의 [Optimize Federated Query Performance using EXPLAIN and EXPLAIN ANALYZE in Amazon Athena](https://aws.amazon.com/blogs/big-data/optimize-federated-query-performance-using-explain-and-explain-analyze-in-amazon-athena/) 

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/7JUyTqglmNU/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/7JUyTqglmNU)


# Athena EXPLAIN 문 결과 이해
<a name="athena-explain-statement-understanding"></a>

이 주제에서는 Athena `EXPLAIN` 문 결과에 사용되는 연산 용어에 대한 간략한 안내를 제공합니다.

## EXPLAIN 문 출력 유형
<a name="athena-explain-statement-understanding-explain-plan-types"></a>

`EXPLAIN` 문 출력은 다음 두 유형 중 하나입니다.
+ **논리적 계획(Logical plan)** - SQL 엔진이 문을 실행하는 데 사용하는 논리적 계획을 표시합니다. 이 옵션의 구문은 `EXPLAIN` 또는 `EXPLAIN (TYPE LOGICAL)`입니다.
+ **배포된 계획(Distributed plan)** - 배포된 환경의 실행 계획을 표시합니다. 출력은 처리 단계인 조각들을 보여줍니다. 각 계획 조각은 하나 이상의 노드에서 처리됩니다. 조각을 처리하는 노드 간에는 데이터를 교환할 수 있습니다. 이 옵션의 구문은 `EXPLAIN (TYPE DISTRIBUTED)`입니다.

  배포된 계획의 출력에서 조각(처리 단계)은 `Fragment` *number* [*fragment\$1type*]으로 표시됩니다. 여기서 *number*는 0부터 시작하는 정수이고 *fragment\$1type*은 조각이 노드에 의해 실행되는 방식을 지정합니다. 데이터 교환의 레이아웃에 대한 통찰력을 제공하는 조각 유형은 다음 표에 설명되어 있습니다.  
**배포된 계획 조각 유형**    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/athena/latest/ug/athena-explain-statement-understanding.html)

## Exchange
<a name="athena-explain-statement-understanding-exchange-types"></a>

교환 관련 용어는 작업자 노드 간에 데이터가 교환되는 방식을 설명합니다. 전송은 로컬 또는 원격일 수 있습니다.

**LocalExchange [*exchange\$1type*] **  
쿼리의 여러 단계에 대해 작업자 노드 내에서 로컬로 데이터를 전송합니다. *exchange\$1type*의 값은 이 단원의 뒤에서 설명한 대로 논리적 교환 또는 배포된 교환 유형 중 하나일 수 있습니다.

**RemoteExchange [*exchange\$1type*] **  
쿼리의 여러 단계에 대해 작업자 노드 간에 데이터를 전송합니다. *exchange\$1type*의 값은 이 단원의 뒤에서 설명한 대로 논리적 교환 또는 배포된 교환 유형 중 하나일 수 있습니다.

### 논리적 교환 유형
<a name="athena-explain-statement-understanding-exchange-types-logical"></a>

다음 교환 유형은 논리적 계획의 교환 단계 중에 수행되는 작업에 대해 설명합니다.
+ **`GATHER`** - 하나의 작업자 노드가 다른 모든 작업자 노드로부터 출력을 수집합니다. 예를 들어, select 쿼리의 마지막 단계에서 모든 노드의 결과를 수집하고 결과를 Amazon S3에 기록합니다.
+ **`REPARTITION`** - 다음 연산자에 적용하는 데 필요한 분할 스키마를 기반으로 특정 작업자에게 행 데이터를 보냅니다.
+ **`REPLICATE`** - 행 데이터를 모든 작업자에게 복사합니다.

### 배포된 교환 유형
<a name="athena-explain-statement-understanding-exchange-types-distributed"></a>

다음 교환 유형은 배포된 계획의 노드 간에 데이터가 교환될 때 데이터의 레이아웃을 나타냅니다.
+ **`HASH`** - 교환이 해시 함수를 사용하여 여러 대상에 데이터를 배포합니다.
+ **`SINGLE`** - 교환이 하나의 대상에 데이터를 배포합니다.

## 스캔
<a name="athena-explain-statement-understanding-scanning"></a>

다음 용어는 쿼리 중에 데이터를 스캔하는 방식을 설명합니다.

**TableScan **  
Amazon S3 또는 Apache Hive 커넥터에서 온 테이블의 소스 데이터를 스캔하고 필터 조건자로부터 발생된 파티션 정리를 적용합니다.

**ScanFilter **  
Amazon S3 또는 Apache Hive 커넥터에서 온 테이블의 소스 데이터를 스캔하고 필터 조건자 및 파티션 정리 전반에 적용되지 않은 추가 필터 조건자로부터 발생된 파티션 정리를 적용합니다.

**ScanFilterProject **  
먼저 Amazon S3 또는 Apache Hive 커넥터에서 온 테이블의 소스 데이터를 스캔하고 필터 조건자 및 파티션 정리 전반에 적용되지 않은 추가 필터 조건자로부터 발생된 파티션 정리를 적용합니다. 그런 다음 출력 데이터의 메모리 레이아웃을 새로운 프로젝션으로 수정하여 후속 단계의 성능을 향상시킵니다.

## 조인
<a name="athena-explain-statement-understanding-join"></a>

두 테이블 간에 데이터를 조인합니다. 조인은 조인 유형 및 배포 유형별로 범주화할 수 있습니다.

### 조인 유형
<a name="athena-explain-statement-understanding-join-types"></a>

조인 유형은 조인 작업이 발생하는 방식을 정의합니다.

**CrossJoin** - 조인된 두 테이블의 데카르트 곱을 산출합니다.

**InnerJoin** - 두 테이블에서 일치하는 값을 가진 레코드를 선택합니다.

**LeftJoin** - 왼쪽 테이블의 모든 레코드와 오른쪽 테이블의 일치하는 레코드를 선택합니다. 일치하는 항목이 없으면 오른쪽의 결과는 NULL입니다.

**RightJoin** - 오른쪽 테이블의 모든 레코드와 왼쪽 테이블의 일치하는 레코드를 선택합니다. 일치하는 항목이 없으면 왼쪽의 결과는 NULL입니다.

**FullJoin** - 왼쪽 또는 오른쪽 테이블 레코드에서 일치항목이 있는 모든 레코드를 선택합니다. 조인된 테이블에는 두 테이블의 모든 레코드가 포함되며 양쪽에서 누락된 일치 항목에 대해서는 NULL을 채웁니다.

**참고**  
성능상의 이유로 쿼리 엔진은 조인 쿼리를 다른 조인 유형으로 다시 작성하여 같은 결과를 낼 수 있습니다. 예를 들어, 하나의 테이블에 조건자가 있는 내부 조인 쿼리는 `CrossJoin`으로 다시 작성할 수 있습니다. 이렇게 하면 조건자가 테이블의 스캔 단계로 푸시다운되어 더 적은 데이터가 검색됩니다.

### 조인 배포 유형
<a name="athena-explain-statement-understanding-join-distribution-types"></a>

배포 유형은 조인 작업이 수행될 때 작업자 노드 간에 데이터가 교환되는 방식을 정의합니다.

**분할식(Partitioned)** - 왼쪽 테이블과 오른쪽 테이블이 모든 작업자 노드에서 모두 해시 분할됩니다. 분할식 배포는 각 노드에서 더 적은 메모리를 소비합니다. 분할된 배포는 복제된 조인보다 훨씬 느릴 수 있습니다. 두 개의 큰 테이블을 조인할 때 분할식 조인이 적합합니다.

**복제식(Replicated)**- 조인 작업을 수행하기 위해 한 테이블은 모든 작업자 노드에서 해시 분할되고 다른 테이블은 모든 작업자 노드에 복제됩니다. 복제식 배포는 분할식 조인보다 훨씬 빠를 수 있지만 각 작업자 노드에서 더 많은 메모리를 소비합니다. 복제된 테이블이 너무 크면 작업자 노드에서 메모리 부족 오류가 발생할 수 있습니다. 조인된 테이블 중 하나가 작은 경우 복제식 조인이 적합합니다.

# PREPARE
<a name="sql-prepare"></a>

`statement_name` 이름으로 나중에 실행할 SQL 문을 작성합니다. 문에는 물음표로 표시되는 파라미터가 포함될 수 있습니다. 파라미터 값을 제공하고 준비된 문을 실행하려면 [EXECUTE](sql-execute.md)을 사용합니다.

## 시놉시스
<a name="sql-prepare-synopsis"></a>

```
PREPARE statement_name FROM statement
```

다음 표는 이러한 파라미터를 설명합니다.


****  

| 파라미터 | 설명 | 
| --- | --- | 
| statement\$1name | 준비되는 문의 이름입니다. 이 이름은 작업 그룹 내에서 고유해야 합니다. | 
| statement | SELECT, CTAS 또는 INSERT INTO 쿼리. | 

**참고**  
작업 그룹에서 준비된 문의 최대 개수는 1000입니다.

## 예시
<a name="sql-prepare-examples"></a>

다음 예제에서는 파라미터 없이 select 쿼리를 준비합니다.

```
PREPARE my_select1 FROM 
SELECT * FROM nation
```

다음 예제에서는 파라미터를 포함하여 select 쿼리를 준비합니다. `productid` 및 `quantity`에 대한 값은 `EXECUTE` 문의 `USING` 절로 제공됩니다.

```
PREPARE my_select2 FROM 
SELECT order FROM orders WHERE productid = ? and quantity < ?
```

다음 예제에서는 insert 쿼리를 준비합니다.

```
PREPARE my_insert FROM 
INSERT INTO cities_usa (city, state) 
SELECT city, state 
FROM cities_world 
WHERE country = ?
```

## 추가 리소스
<a name="sql-prepare-additional-resources"></a>

[준비된 문 사용](querying-with-prepared-statements-querying.md)

[EXECUTE](sql-execute.md)

[DEALLOCATE PREPARE](sql-deallocate-prepare.md)

[INSERT INTO](insert-into.md)

# EXECUTE
<a name="sql-execute"></a>

준비된 문을 `statement_name` 이름으로 실행합니다. 준비된 문에서 물음표에 대한 파라미터 값은 쉼표로 구분된 목록의 `USING` 절로 정의됩니다. 준비된 문을 생성하려면 [PREPARE](sql-prepare.md)을 사용합니다.

## 시놉시스
<a name="sql-execute-synopsis"></a>

```
EXECUTE statement_name [ USING parameter1[, parameter2, ... ] ]
```

## 예시
<a name="sql-execute-examples"></a>

다음 예제에서는 파라미터 없이 쿼리를 준비하고 실행합니다.

```
PREPARE my_select1 FROM 
SELECT name FROM nation 
EXECUTE my_select1
```

다음 예제에서는 단일 파라미터를 사용해 쿼리를 준비하고 실행합니다.

```
PREPARE my_select2 FROM 
SELECT * FROM "my_database"."my_table" WHERE year = ? 
EXECUTE my_select2 USING 2012
```

이는 다음과 동일합니다.

```
SELECT * FROM "my_database"."my_table" WHERE year = 2012
```

다음 예제에서는 두 개의 파라미터를 사용해 쿼리를 준비하고 실행합니다.

```
PREPARE my_select3 FROM 
SELECT order FROM orders WHERE productid = ? and quantity < ? 
EXECUTE my_select3 USING 346078, 12
```

## 추가 리소스
<a name="sql-execute-additional-resources"></a>

[준비된 문 사용](querying-with-prepared-statements-querying.md)

[PREPARE](sql-prepare.md)

[INSERT INTO](insert-into.md)

# DEALLOCATE PREPARE
<a name="sql-deallocate-prepare"></a>

현재 작업 그룹의 준비된 문에서 지정된 이름을 가진 준비된 문을 제거합니다.

## 시놉시스
<a name="sql-deallocate-prepare-synopsis"></a>

```
DEALLOCATE PREPARE statement_name
```

## 예시
<a name="sql-deallocate-prepare-examples"></a>

다음 예제는 현재 작업 그룹에서 준비된 문 `my_select1`을 제거합니다.

```
DEALLOCATE PREPARE my_select1
```

## 추가 리소스
<a name="sql-deallocate-prepare-additional-resources"></a>

[준비된 문 사용](querying-with-prepared-statements-querying.md)

[PREPARE](sql-prepare.md)

# UNLOAD
<a name="unload"></a>

`SELECT` 문의 쿼리 결과를 지정된 데이터 형식으로 작성합니다. `UNLOAD`에 지원되는 형식에는 Apache Parquet, ORC, Apache Avro, JSON이 있습니다. CSV는 Athena `SELECT` 명령에서 지원하는 유일한 출력 형식이지만 다양한 출력 형식을 지원하는 `UNLOAD` 명령을 사용하여 `SELECT` 쿼리를 묶고 `UNLOAD`에서 지원하는 형식 중 하나로 출력을 다시 작성할 수 있습니다.

`CREATE TABLE AS`(CTAS) 문을 사용하여 CSV 외의 형식으로 데이터를 출력할 수 있지만 CTAS 문은 Athena에서 테이블을 만들어야 합니다. `UNLOAD` 문은 `SELECT` 쿼리의 결과를 CSV 외의 형식으로 출력할 때 유용하지만 관련된 테이블을 필요로 하지 않습니다. 예를 들어 어떤 다운스트림 애플리케이션은 `SELECT` 쿼리 결과가 JSON 형식이 되도록 요구할 수 있고, 추가적인 분석을 위해 `SELECT` 쿼리의 결과를 사용하려는 경우 Parquet 또는 ORC가 CSV에 대해 성능상 이점을 제공할 수 있습니다. 

## 고려 사항 및 제한 사항
<a name="unload-considerations-and-limitations"></a>

Athena에서 `UNLOAD` 문을 사용할 때는 다음 사항을 유의해야 합니다.
+ **파일의 전역 정렬 없음** – `UNLOAD` 결과는 여러 개의 파일에 병렬로 작성됩니다. `UNLOAD` 문의 `SELECT` 쿼리에 정렬 순서가 지정된 경우 각 파일의 내용은 순서대로 정렬되지만 파일들은 서로 간에 정렬되지 않습니다.
+ **분리된 데이터가 삭제되지 않음** - 실패 시 Athena는 분리된 데이터를 삭제하지 않습니다. 이 동작은 CTAS 및 `INSERT INTO` 문의 동작과 같습니다.
+ **최대 파티션** - `UNLOAD`에 사용할 수 있는 최대 파티션 수는 100개입니다.
+ **메타데이터 및 매니페스트 파일** - Athena는 각각의 `UNLOAD` 쿼리에 대해 메타데이터 파일 및 데이터 매니페스트 파일을 생성합니다. 매니페스트는 쿼리가 작성한 파일을 추적합니다. 두 파일은 모두 Amazon S3의 Athena 쿼리 결과 위치에 저장됩니다. 자세한 내용은 [쿼리 출력 파일 식별](querying-finding-output-files.md#querying-identifying-output-files) 단원을 참조하세요.
+ **암호화** – `UNLOAD` 출력 파일은 Amazon S3에 사용되는 암호화 구성에 따라 암호화됩니다. `UNLOAD` 결과를 암호화하도록 암호화 구성을 설정하려면 [EncryptionConfiguration API](https://docs.aws.amazon.com/athena/latest/APIReference/API_EncryptionConfiguration.html)를 사용합니다.
+ **준비된 문** – `UNLOAD`는 준비된 문과 함께 사용할 수 있습니다. Athena의 준비된 문에 대한 자세한 내용은 [파라미터화된 쿼리 사용](querying-with-prepared-statements.md) 단원을 참조하세요.
+ **서비스 할당량** - `UNLOAD`는 DML 쿼리 할당량을 사용합니다. 할당량에 관한 자세한 내용은 [Service Quotas](service-limits.md) 단원을 참조하세요.
+ **예상 버킷 소유자** – 예상 버킷 소유자 설정은 `UNLOAD` 쿼리에 지정된 대상 Amazon S3 위치에 적용되지 않습니다. 예상 버킷 소유자 설정은 Athena 쿼리 결과에 대해 지정한 Amazon S3 출력 위치에만 적용됩니다. 자세한 내용은 [Athena 콘솔을 사용하여 쿼리 결과 위치 지정](query-results-specify-location-console.md) 섹션을 참조하세요.

## 구문
<a name="unload-syntax"></a>

`UNLOAD` 문은 다음 구문을 사용합니다.

```
UNLOAD (SELECT col_name[, ...] FROM old_table) 
TO 's3://amzn-s3-demo-bucket/my_folder/' 
WITH ( property_name = 'expression' [, ...] )
```

파티션에 쓰는 경우를 제외하고, `TO` 대상에는 데이터가 없는 Amazon S3의 위치를 지정해야 합니다. `UNLOAD` 쿼리는 지정된 위치에 데이터를 쓰기 전에 버킷 위치가 비어 있는지 확인합니다. `UNLOAD`는 지정된 위치에 이미 데이터가 있는 경우 해당 위치에 데이터를 쓰지 않습니다. `UNLOAD`는 기존 데이터를 덮어쓰지 않습니다. 버킷 위치를 `UNLOAD`의 대상으로 재사용하려면 버킷 위치에서 데이터를 삭제한 다음 쿼리를 다시 실행합니다.

`UNLOAD`가 파티션에 쓸 때는 이 동작이 다르다는 점에 유의하세요. `SELECT` 문, `TO` 위치, 파티션이 동일한 같은 `UNLOAD` 쿼리를 여러 번 실행하는 경우 각 `UNLOAD` 쿼리는 지정된 위치와 파티션에 있는 Amazon S3로 데이터를 언로드합니다.

### 파라미터
<a name="unload-parameters"></a>

*property\$1name*에 가능한 값은 다음과 같습니다.

** format = '*file\$1format*'**  
필수 사항입니다. 출력의 파일 형식을 지정합니다. *file\$1format*에 가능한 값은 `ORC`, `PARQUET`, `AVRO`, `JSON`, 또는 `TEXTFILE`입니다.

** compression = '*compression\$1format*'**  
선택 사항. 이 옵션은 ORC 및 Parquet 형식에만 특정합니다. ORC은 기본값이 `zlib`이고, Parquet는 기본값이 `gzip`입니다. 지원되는 압축 형식에 대한 자세한 내용은 [Athena 압축 지원](https://docs.aws.amazon.com/athena/latest/ug/compression-formats.html)을 참조하세요.  
이 옵션은 `AVRO` 형식에 적용되지 않습니다. Athena는 `JSON` 및 `TEXTFILE` 형식에 `gzip`를 사용합니다.

**compression\$1level = *compression\$1level* **  
선택 사항. ZSTD 압축에 사용할 압축 수준입니다. 이 속성은 ZSTD 압축에만 적용됩니다. 자세한 내용은 [ZSTD 압축 수준 사용](compression-support-zstd-levels.md) 섹션을 참조하세요.

** field\$1delimiter = '*delimiter*'**  
선택 사항. CSV, TSV 및 기타 텍스트 형식에 대해 단일 문자의 필드 구분 기호를 지정합니다. 다음은 쉼표를 구분 기호로 지정한 예입니다.  

```
WITH (field_delimiter = ',')
```
현재 여러 문자로 된 필드 구분 기호는 지원되지 않습니다. 필드 구분 기호를 지정하지 않으면 8진법 문자 `\001`(^A)이 사용됩니다.

** partitioned\$1by = ARRAY[ *col\$1name*[,...] ] **  
선택 사항. 출력을 분할하는 기준이 되는 열의 배열 목록입니다.  
`SELECT` 문에서 분할된 열의 이름이 문의 열 목록 마지막에 있는지 확인합니다.

## 예제
<a name="unload-examples"></a>

다음 예제는 `SELECT` 쿼리의 출력을 JSON 형식으로 Amazon S3 위치 `s3://amzn-s3-demo-bucket/unload_test_1/`에 작성합니다.

```
UNLOAD (SELECT * FROM old_table) 
TO 's3://amzn-s3-demo-bucket/unload_test_1/' 
WITH (format = 'JSON')
```

다음 예제는 `SELECT` 쿼리의 출력을, Snappy 압축을 사용해 Parquet 형식으로 작성합니다.

```
UNLOAD (SELECT * FROM old_table) 
TO 's3://amzn-s3-demo-bucket/' 
WITH (format = 'PARQUET',compression = 'SNAPPY')
```

다음 예제는 마지막 열을 기준으로 출력을 분할하여 네 개의 열을 텍스트 형식으로 작성합니다.

```
UNLOAD (SELECT name1, address1, comment1, key1 FROM table1) 
TO 's3://amzn-s3-demo-bucket/ partitioned/' 
WITH (format = 'TEXTFILE', partitioned_by = ARRAY['key1'])
```

다음 예제에서는 Parquet 파일 형식, ZSTD 압축 및 ZSTD 압축 수준 4를 사용하여 쿼리 결과를 지정된 위치로 언로드합니다.

```
UNLOAD (SELECT * FROM old_table) 
TO 's3://amzn-s3-demo-bucket/' 
WITH (format = 'PARQUET', compression = 'ZSTD', compression_level = 4)
```

## 추가 리소스
<a name="unload-additional-resources"></a>
+ *AWS 빅 데이터 블로그*의 [Simplify your ETL and ML pipelines using the Amazon Athena UNLOAD feature](https://aws.amazon.com/blogs/big-data/simplify-your-etl-and-ml-pipelines-using-the-amazon-athena-unload-feature/).

# Amazon Athena의 함수
<a name="functions"></a>

Athena 엔진 버전 간 함수 변경 사항에 대해서는 [Athena 엔진 버전 관리](engine-versions.md) 섹션을 참조하세요. `AT TIME ZONE` 연산자에 사용할 수 있는 표준 시간대 목록은 [지원되는 시간대 사용](athena-supported-time-zones.md)를 참조하세요.

**Topics**
+ [Athena 엔진 버전 3](functions-env3.md)

# Athena 엔진 버전 3 함수
<a name="functions-env3"></a>

Athena 엔진 버전 3의 함수는 Trino 기준입니다. Trino 함수, 연산자, 표현식에 대한 자세한 내용은 Trino 설명서에서 [함수 및 연산자](https://trino.io/docs/current/functions.html)와 다음과 같은 하위 섹션을 참조하세요.
+  [집계](https://trino.io/docs/current/functions/aggregate.html) 
+  [배열](https://trino.io/docs/current/functions/array.html) 
+  [이진](https://trino.io/docs/current/functions/binary.html) 
+  [비트](https://trino.io/docs/current/functions/bitwise.html) 
+  [Color(색상)](https://trino.io/docs/current/functions/color.html) 
+  [비교](https://trino.io/docs/current/functions/comparison.html) 
+  [조건](https://trino.io/docs/current/functions/conditional.html) 
+  [변환](https://trino.io/docs/current/functions/conversion.html) 
+  [날짜 및 시간](https://trino.io/docs/current/functions/datetime.html) 
+  [10진수](https://trino.io/docs/current/functions/decimal.html) 
+  [지리 공간](https://trino.io/docs/current/functions/geospatial.html) 
+  [HyperLogLog](https://trino.io/docs/current/functions/hyperloglog.html) 
+  [IP 주소](https://trino.io/docs/current/functions/ipaddress.html) 
+  [JSON](https://trino.io/docs/current/functions/json.html) 
+  [Lambda](https://trino.io/docs/current/functions/lambda.html) 
+  [논리적](https://trino.io/docs/current/functions/logical.html) 
+  [기계 학습](https://trino.io/docs/current/functions/ml.html) 
+  [지도](https://trino.io/docs/current/functions/map.html) 
+  [수학 연산](https://trino.io/docs/current/functions/math.html) 
+  [분위수 다이제스트](https://trino.io/docs/current/functions/qdigest.html) 
+  [정규식](https://trino.io/docs/current/functions/regexp.html) 
+  [세션](https://trino.io/docs/current/functions/session.html) 
+  [세트 다이제스트](https://trino.io/docs/current/functions/setdigest.html) 
+  [문자열](https://trino.io/docs/current/functions/string.html) 
+  [표](https://trino.io/docs/current/functions/table.html) 
+  [Teradata](https://trino.io/docs/current/functions/teradata.html) 
+  [T-다이제스트](https://trino.io/docs/current/functions/tdigest.html) 
+  [URL](https://trino.io/docs/current/functions/url.html) 
+  [UUID](https://trino.io/docs/current/functions/uuid.html) 
+  [Window](https://trino.io/docs/current/functions/window.html) 

## invoker\$1principal() 함수
<a name="functions-env3-invoker-principal"></a>

`invoker_principal` 함수는 Athena 엔진 버전 3에만 있으며 Trino에는 없습니다.

함수를 호출하여 쿼리를 실행한 보안 주체(IAM 역할 또는 Identity Center 자격 증명)의 ARN이 포함된 `VARCHAR`를 반환합니다. 예를 들어 쿼리 호출자가 IAM 역할의 권한을 사용하여 쿼리를 실행하는 경우 함수는 IAM 역할의 ARN을 반환합니다. 쿼리를 실행하는 역할은 `LakeFormation:GetDataLakePrincipal` 작업을 허용해야 합니다.

### 사용법
<a name="functions-invoker-principal-usage"></a>

```
SELECT invoker_principal()
```

다음 표는 결과 예시를 보여줍니다.


****  

| \$1 | \$1col0 | 
| --- | --- | 
| 1 | arn:aws:iam::111122223333:role/Admin | 

# 지원되는 시간대 사용
<a name="athena-supported-time-zones"></a>

`SELECT timestamp` 문에서 `AT TIME ZONE` 연산자를 사용하여 다음 예제와 같이 반환된 타임스탬프에 시간대를 지정할 수 있습니다.

```
SELECT timestamp '2012-10-31 01:00 UTC' AT TIME ZONE 'America/Los_Angeles' AS la_time;
```

**결과**

```
la_time

2012-10-30 18:00:00.000 America/Los_Angeles
```

Athena에서 지원되는 시간대 목록을 보려면 이 주제의 끝 부분에 있는 [지원되는 시간대 목록](#athena-supported-time-zones-list)을 확장하세요.

## 시간대 함수 및 예제
<a name="athena-supported-time-zones-functions-examples"></a>

다음은 시간대와 관련된 몇 가지 추가 함수 및 예제입니다.
+ **at\$1timezone(*타임스탬프*, *영역*)** – *영역*에 해당하는 현지 시간의 *타임스탬프* 값을 반환합니다.

  **예제**

  ```
  SELECT at_timezone(timestamp '2021-08-22 00:00 UTC', 'Canada/Newfoundland')
  ```

  **결과**

  ```
  2021-08-21 21:30:00.000 Canada/Newfoundland
  ```
+ **timezone\$1hour(*타임스탬프*)** – 타임스탬프에서 시간대의 시간 오프셋을 `bigint`로 반환합니다.

  **예제**

  ```
  SELECT timezone_hour(timestamp '2021-08-22 04:00 UTC' AT TIME ZONE 'Canada/Newfoundland')
  ```

  **결과**

  ```
  -2
  ```
+ **timezone\$1minute(*타임스탬프*)** – *타임스탬프*에서 시간대의 분 오프셋을 `bigint`로 반환합니다.

  **예제**

  ```
  SELECT timezone_minute(timestamp '2021-08-22 04:00 UTC' AT TIME ZONE 'Canada/Newfoundland')
  ```

  **결과**

  ```
  -30
  ```
+ **with\$1timezone(*타임스탬프*, *영역*)** – 지정한 *타임스탬프* 및 *영역* 값에서 시간대와 함께 타임스탬프를 반환합니다.

  **예제**

  ```
  SELECT with_timezone(timestamp '2021-08-22 04:00', 'Canada/Newfoundland')
  ```

  **결과**

  ```
  2021-08-22 04:00:00.000 Canada/Newfoundland
  ```

## 지원되는 시간대 목록
<a name="athena-supported-time-zones-list"></a>

다음 목록에는 Athena에서 `AT TIME ZONE` 연산자에 사용할 수 있는 표준 시간대가 포함되어 있습니다. 시간대 관련 추가 함수 및 예제는 [시간대 함수 및 예제](#athena-supported-time-zones-functions-examples) 단원을 참조하세요.

```
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
Africa/Bamako
Africa/Bangui
Africa/Banjul
Africa/Bissau
Africa/Blantyre
Africa/Brazzaville
Africa/Bujumbura
Africa/Cairo
Africa/Casablanca
Africa/Ceuta
Africa/Conakry
Africa/Dakar
Africa/Dar_es_Salaam
Africa/Djibouti
Africa/Douala
Africa/El_Aaiun
Africa/Freetown
Africa/Gaborone
Africa/Harare
Africa/Johannesburg
Africa/Juba
Africa/Kampala
Africa/Khartoum
Africa/Kigali
Africa/Kinshasa
Africa/Lagos
Africa/Libreville
Africa/Lome
Africa/Luanda
Africa/Lubumbashi
Africa/Lusaka
Africa/Malabo
Africa/Maputo
Africa/Maseru
Africa/Mbabane
Africa/Mogadishu
Africa/Monrovia
Africa/Nairobi
Africa/Ndjamena
Africa/Niamey
Africa/Nouakchott
Africa/Ouagadougou
Africa/Porto-Novo
Africa/Sao_Tome
Africa/Timbuktu
Africa/Tripoli
Africa/Tunis
Africa/Windhoek
America/Adak
America/Anchorage
America/Anguilla
America/Antigua
America/Araguaina
America/Argentina/Buenos_Aires
America/Argentina/Catamarca
America/Argentina/ComodRivadavia
America/Argentina/Cordoba
America/Argentina/Jujuy
America/Argentina/La_Rioja
America/Argentina/Mendoza
America/Argentina/Rio_Gallegos
America/Argentina/Salta
America/Argentina/San_Juan
America/Argentina/San_Luis
America/Argentina/Tucuman
America/Argentina/Ushuaia
America/Aruba
America/Asuncion
America/Atikokan
America/Atka
America/Bahia
America/Bahia_Banderas
America/Barbados
America/Belem
America/Belize
America/Blanc-Sablon
America/Boa_Vista
America/Bogota
America/Boise
America/Buenos_Aires
America/Cambridge_Bay
America/Campo_Grande
America/Cancun
America/Caracas
America/Catamarca
America/Cayenne
America/Cayman
America/Chicago
America/Chihuahua
America/Coral_Harbour
America/Cordoba
America/Costa_Rica
America/Creston
America/Cuiaba
America/Curacao
America/Danmarkshavn
America/Dawson
America/Dawson_Creek
America/Denver
America/Detroit
America/Dominica
America/Edmonton
America/Eirunepe
America/El_Salvador
America/Ensenada
America/Fort_Nelson
America/Fort_Wayne
America/Fortaleza
America/Glace_Bay
America/Godthab
America/Goose_Bay
America/Grand_Turk
America/Grenada
America/Guadeloupe
America/Guatemala
America/Guayaquil
America/Guyana
America/Halifax
America/Havana
America/Hermosillo
America/Indiana/Indianapolis
America/Indiana/Knox
America/Indiana/Marengo
America/Indiana/Petersburg
America/Indiana/Tell_City
America/Indiana/Vevay
America/Indiana/Vincennes
America/Indiana/Winamac
America/Indianapolis
America/Inuvik
America/Iqaluit
America/Jamaica
America/Jujuy
America/Juneau
America/Kentucky/Louisville
America/Kentucky/Monticello
America/Knox_IN
America/Kralendijk
America/La_Paz
America/Lima
America/Los_Angeles
America/Louisville
America/Lower_Princes
America/Maceio
America/Managua
America/Manaus
America/Marigot
America/Martinique
America/Matamoros
America/Mazatlan
America/Mendoza
America/Menominee
America/Merida
America/Metlakatla
America/Mexico_City
America/Miquelon
America/Moncton
America/Monterrey
America/Montevideo
America/Montreal
America/Montserrat
America/Nassau
America/New_York
America/Nipigon
America/Nome
America/Noronha
America/North_Dakota/Beulah
America/North_Dakota/Center
America/North_Dakota/New_Salem
America/Ojinaga
America/Panama
America/Pangnirtung
America/Paramaribo
America/Phoenix
America/Port-au-Prince
America/Port_of_Spain
America/Porto_Acre
America/Porto_Velho
America/Puerto_Rico
America/Punta_Arenas
America/Rainy_River
America/Rankin_Inlet
America/Recife
America/Regina
America/Resolute
America/Rio_Branco
America/Rosario
America/Santa_Isabel
America/Santarem
America/Santiago
America/Santo_Domingo
America/Sao_Paulo
America/Scoresbysund
America/Shiprock
America/Sitka
America/St_Barthelemy
America/St_Johns
America/St_Kitts
America/St_Lucia
America/St_Thomas
America/St_Vincent
America/Swift_Current
America/Tegucigalpa
America/Thule
America/Thunder_Bay
America/Tijuana
America/Toronto
America/Tortola
America/Vancouver
America/Virgin
America/Whitehorse
America/Winnipeg
America/Yakutat
America/Yellowknife
Antarctica/Casey
Antarctica/Davis
Antarctica/DumontDUrville
Antarctica/Macquarie
Antarctica/Mawson
Antarctica/McMurdo
Antarctica/Palmer
Antarctica/Rothera
Antarctica/South_Pole
Antarctica/Syowa
Antarctica/Troll
Antarctica/Vostok
Arctic/Longyearbyen
Asia/Aden
Asia/Almaty
Asia/Amman
Asia/Anadyr
Asia/Aqtau
Asia/Aqtobe
Asia/Ashgabat
Asia/Ashkhabad
Asia/Atyrau
Asia/Baghdad
Asia/Bahrain
Asia/Baku
Asia/Bangkok
Asia/Barnaul
Asia/Beirut
Asia/Bishkek
Asia/Brunei
Asia/Calcutta
Asia/Chita
Asia/Choibalsan
Asia/Chongqing
Asia/Chungking
Asia/Colombo
Asia/Dacca
Asia/Damascus
Asia/Dhaka
Asia/Dili
Asia/Dubai
Asia/Dushanbe
Asia/Gaza
Asia/Harbin
Asia/Hebron
Asia/Ho_Chi_Minh
Asia/Hong_Kong
Asia/Hovd
Asia/Irkutsk
Asia/Istanbul
Asia/Jakarta
Asia/Jayapura
Asia/Jerusalem
Asia/Kabul
Asia/Kamchatka
Asia/Karachi
Asia/Kashgar
Asia/Kathmandu
Asia/Katmandu
Asia/Khandyga
Asia/Kolkata
Asia/Krasnoyarsk
Asia/Kuala_Lumpur
Asia/Kuching
Asia/Kuwait
Asia/Macao
Asia/Macau
Asia/Magadan
Asia/Makassar
Asia/Manila
Asia/Muscat
Asia/Nicosia
Asia/Novokuznetsk
Asia/Novosibirsk
Asia/Omsk
Asia/Oral
Asia/Phnom_Penh
Asia/Pontianak
Asia/Pyongyang
Asia/Qatar
Asia/Qyzylorda
Asia/Rangoon
Asia/Riyadh
Asia/Saigon
Asia/Sakhalin
Asia/Samarkand
Asia/Seoul
Asia/Shanghai
Asia/Singapore
Asia/Srednekolymsk
Asia/Taipei
Asia/Tashkent
Asia/Tbilisi
Asia/Tehran
Asia/Tel_Aviv
Asia/Thimbu
Asia/Thimphu
Asia/Tokyo
Asia/Tomsk
Asia/Ujung_Pandang
Asia/Ulaanbaatar
Asia/Ulan_Bator
Asia/Urumqi
Asia/Ust-Nera
Asia/Vientiane
Asia/Vladivostok
Asia/Yakutsk
Asia/Yangon
Asia/Yekaterinburg
Asia/Yerevan
Atlantic/Azores
Atlantic/Bermuda
Atlantic/Canary
Atlantic/Cape_Verde
Atlantic/Faeroe
Atlantic/Faroe
Atlantic/Jan_Mayen
Atlantic/Madeira
Atlantic/Reykjavik
Atlantic/South_Georgia
Atlantic/St_Helena
Atlantic/Stanley
Australia/ACT
Australia/Adelaide
Australia/Brisbane
Australia/Broken_Hill
Australia/Canberra
Australia/Currie
Australia/Darwin
Australia/Eucla
Australia/Hobart
Australia/LHI
Australia/Lindeman
Australia/Lord_Howe
Australia/Melbourne
Australia/NSW
Australia/North
Australia/Perth
Australia/Queensland
Australia/South
Australia/Sydney
Australia/Tasmania
Australia/Victoria
Australia/West
Australia/Yancowinna
Brazil/Acre
Brazil/DeNoronha
Brazil/East
Brazil/West
CET
CST6CDT
Canada/Atlantic
Canada/Central
Canada/Eastern
Canada/Mountain
Canada/Newfoundland
Canada/Pacific
Canada/Saskatchewan
Canada/Yukon
Chile/Continental
Chile/EasterIsland
Cuba
EET
EST5EDT
Egypt
Eire
Europe/Amsterdam
Europe/Andorra
Europe/Astrakhan
Europe/Athens
Europe/Belfast
Europe/Belgrade
Europe/Berlin
Europe/Bratislava
Europe/Brussels
Europe/Bucharest
Europe/Budapest
Europe/Busingen
Europe/Chisinau
Europe/Copenhagen
Europe/Dublin
Europe/Gibraltar
Europe/Guernsey
Europe/Helsinki
Europe/Isle_of_Man
Europe/Istanbul
Europe/Jersey
Europe/Kaliningrad
Europe/Kiev
Europe/Kirov
Europe/Lisbon
Europe/Ljubljana
Europe/London
Europe/Luxembourg
Europe/Madrid
Europe/Malta
Europe/Mariehamn
Europe/Minsk
Europe/Monaco
Europe/Moscow
Europe/Nicosia
Europe/Oslo
Europe/Paris
Europe/Podgorica
Europe/Prague
Europe/Riga
Europe/Rome
Europe/Samara
Europe/San_Marino
Europe/Sarajevo
Europe/Simferopol
Europe/Skopje
Europe/Sofia
Europe/Stockholm
Europe/Tallinn
Europe/Tirane
Europe/Tiraspol
Europe/Ulyanovsk
Europe/Uzhgorod
Europe/Vaduz
Europe/Vatican
Europe/Vienna
Europe/Vilnius
Europe/Volgograd
Europe/Warsaw
Europe/Zagreb
Europe/Zaporozhye
Europe/Zurich
GB
GB-Eire
Hongkong
Iceland
Indian/Antananarivo
Indian/Chagos
Indian/Christmas
Indian/Cocos
Indian/Comoro
Indian/Kerguelen
Indian/Mahe
Indian/Maldives
Indian/Mauritius
Indian/Mayotte
Indian/Reunion
Iran
Israel
Jamaica
Japan
Kwajalein
Libya
MET
MST7MDT
Mexico/BajaNorte
Mexico/BajaSur
Mexico/General
NZ
NZ-CHAT
Navajo
PRC
PST8PDT
Pacific/Apia
Pacific/Auckland
Pacific/Bougainville
Pacific/Chatham
Pacific/Chuuk
Pacific/Easter
Pacific/Efate
Pacific/Enderbury
Pacific/Fakaofo
Pacific/Fiji
Pacific/Funafuti
Pacific/Galapagos
Pacific/Gambier
Pacific/Guadalcanal
Pacific/Guam
Pacific/Honolulu
Pacific/Johnston
Pacific/Kiritimati
Pacific/Kosrae
Pacific/Kwajalein
Pacific/Majuro
Pacific/Marquesas
Pacific/Midway
Pacific/Nauru
Pacific/Niue
Pacific/Norfolk
Pacific/Noumea
Pacific/Pago_Pago
Pacific/Palau
Pacific/Pitcairn
Pacific/Pohnpei
Pacific/Ponape
Pacific/Port_Moresby
Pacific/Rarotonga
Pacific/Saipan
Pacific/Samoa
Pacific/Tahiti
Pacific/Tarawa
Pacific/Tongatapu
Pacific/Truk
Pacific/Wake
Pacific/Wallis
Pacific/Yap
Poland
Portugal
ROK
Singapore
Turkey
US/Alaska
US/Aleutian
US/Arizona
US/Central
US/East-Indiana
US/Eastern
US/Hawaii
US/Indiana-Starke
US/Michigan
US/Mountain
US/Pacific
US/Pacific-New
US/Samoa
W-SU
WET
```