

# 워크로드 관리
<a name="workload-management"></a>

Athena의 작업 그룹, 용량 관리, 성능 튜닝, 압축 지원, 태그, 서비스 할당량 기능을 사용하여 워크로드를 관리할 수 있습니다.

**Topics**
+ [작업 그룹을 사용하여 쿼리 액세스 및 비용 제어](workgroups-manage-queries-control-costs.md)
+ [쿼리 처리 용량 관리](capacity-management.md)
+ [Athena 성능 최적화](performance-tuning.md)
+ [Athena에서 압축 사용](compression-formats.md)
+ [Athena 리소스 태깅](tags.md)
+ [Service Quotas](service-limits.md)

# 작업 그룹을 사용하여 쿼리 액세스 및 비용 제어
<a name="workgroups-manage-queries-control-costs"></a>

Athena 작업 그룹을 사용하여 워크로드를 분리하고, 팀 액세스를 제어하고, 구성을 적용하고, 쿼리 지표를 추적하여 비용을 제어할 수 있습니다.

**워크로드 분리**  
작업 그룹을 사용하여 워크로드를 분리할 수 있습니다. 예를 들어, 보고서 생성과 같은 자동화된 예약 애플리케이션용으로 한 개, 분석가의 임시 사용을 위해 또 다른 한 개, 즉 두 개의 작업 그룹을 만들 수 있습니다.

**팀별 액세스 제어**  
작업 그룹은 IAM 리소스 역할을 하기 때문에 리소스 수준 자격 증명 기반 정책을 사용하여 특정 작업 그룹에 액세스하고 쿼리를 실행할 수 있는 사용자를 제어할 수 있습니다. 조직에서 서로 다른 두 팀의 쿼리를 분리하려면 각 팀에 대해 별도의 작업 그룹을 생성할 수 있습니다. 각 작업 그룹에는 계정의 모든 쿼리가 아닌 해당 작업 그룹의 쿼리에 대한 자체 쿼리 기록 및 저장된 쿼리 목록이 있습니다. 자세한 내용은 [IAM 정책을 사용하여 작업 그룹 액세스 제어](workgroups-iam-policy.md) 섹션을 참조하세요.

**구성 적용**  
선택적으로 작업 그룹에서 실행되는 모든 쿼리에 동일한 작업 그룹 전역 설정을 적용할 수 있습니다. 이러한 설정에는 Amazon S3 쿼리 결과 위치, 예상 버킷 소유자, 암호화 및 쿼리 결과 버킷에 기록된 객체의 제어가 포함됩니다. 자세한 내용은 [Override client-side settings(클라이언트 측 설정 재정의)](workgroups-settings-override.md) 섹션을 참조하세요.

**쿼리 지표, 쿼리 이벤트를 추적하여 비용 제어**  
각 Athena 작업 그룹에 대한 쿼리 지표, 쿼리 이벤트를 추적하여 비용을 제어하려면 다음 기능을 사용할 수 있습니다.
+ **쿼리 지표 게시** - 작업 그룹의 쿼리 지표를 CloudWatch에 게시합니다. Athena 콘솔에서 작업 그룹 각각에 대해 쿼리 지표를 볼 수 있습니다. CloudWatch에서 사용자 지정 대시보드를 생성하고, 이러한 지표에 대한 임계값과 경보를 설정할 수 있습니다. 자세한 내용은 [Athena에서 CloudWatch 쿼리 지표 활성화](athena-cloudwatch-metrics-enable.md) 및 [CloudWatch를 사용하여 Athena 쿼리 지표 모니터링](query-metrics-viewing.md)(을)를 참조하세요.
+ **Athena 사용량 지표 모니터링** - CloudWatch 그래프 및 대시보드를 통해 현재 서비스 사용량을 표시하여 계정이 리소스를 어떻게 사용하는지 확인합니다. 자세한 내용은 [CloudWatch를 사용하여 Athena 사용량 지표 모니터링](monitoring-athena-usage-metrics.md) 섹션을 참조하세요.
+ **쿼리 이벤트 모니터링** - Amazon EventBridge를 사용하여 쿼리의 상태에 대한 실시간 알림을 받습니다. 자세한 내용은 [EventBridge를 사용하여 Athena 쿼리 이벤트 모니터링](athena-events.md) 섹션을 참조하세요.
+ **데이터 사용량 제어 생성** - Athena에서는 쿼리당 및 작업 그룹당 데이터 사용량 제어를 구성할 수 있습니다. Athena는 데이터 사용량이 지정된 임계값을 초과하면 쿼리를 취소하거나 작업 그룹 임계값을 초과하면 Amazon SNS 경보를 활성화합니다. 자세한 내용은 [쿼리당 및 작업 그룹당 데이터 사용량 제어 구성](workgroups-setting-control-limits-cloudwatch.md) 섹션을 참조하세요.
+ **비용 할당 태그 사용** - Billing and Cost Management 콘솔을 사용하여 작업 그룹에 비용 할당 태그를 지정할 수 있습니다. 작업 그룹에서의 쿼리 실행과 관련된 비용은 비용 및 사용 보고서에 해당 비용 할당 태그와 함께 나타납니다. 자세한 내용은 *AWS Billing 사용 설명서*에서 [사용자 정의 비용 할당 태그 사용](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/custom-tags.html)을 참조하세요.
+ **용량 예약 사용** - 비용을 추가로 제어하기 위해 사용자가 지정한 데이터 처리 장치 수로 용량 예약을 생성하고 예약에 하나 이상의 작업 그룹을 추가할 수 있습니다. 자세한 내용은 [쿼리 처리 용량 관리](capacity-management.md) 섹션을 참조하세요.

Amazon Athena 작업 그룹을 사용하여 워크로드를 분리하고, 사용자 액세스를 제어하고, 쿼리 사용량 및 비용을 관리하는 방법에 대한 자세한 내용은 AWS 빅 데이터 블로그 게시물 [Amazon Athena 작업 그룹을 사용하여 쿼리 분리 및 비용 관리](https://aws.amazon.com/blogs/big-data/separating-queries-and-managing-costs-using-amazon-athena-workgroups/)를 참조하세요.

**참고**  
이제 Amazon SageMaker Unified Studio(미리 보기) 내에서 Amazon Athena 리소스에 액세스할 수 있어 조직의 데이터에 액세스하고 최상의 도구로 작업하는 데 도움이 됩니다. 저장된 쿼리를 Athena 작업 그룹에서 SageMaker Unified Studio 프로젝트로 마이그레이션하고, 기존 Athena 작업 그룹으로 프로젝트를 구성하고, IAM 역할 업데이트를 통해 필요한 권한을 유지할 수 있습니다. 자세한 내용은 [ Amazon Athena 리소스를 Amazon SageMaker Unified Studio로 마이그레이션(미리 보기)](https://github.com/aws/Unified-Studio-for-Amazon-Sagemaker/tree/main/migration/athena)을 참조하세요.

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

Athena에서 작업 그룹을 사용할 때는 다음 사항을 유의해야 합니다.
+ 각 계정에는 기본 작업 그룹이 있습니다. 작업 그룹을 생성하지 않은 경우 기본적으로 해당 계정의 모든 쿼리는 다음과 같이 기본 작업 그룹에서 실행됩니다. 기본 작업 그룹은 삭제할 수 없습니다. 기본 권한은 모든 인증된 사용자가 이 작업 그룹에 액세스할 수 있도록 허용합니다.
+ 작업 그룹에 액세스할 수 있는 경우 작업 그룹의 설정, 지표, 데이터 사용량 제어 한도를 볼 수 있습니다. 추가 권한으로 설정 및 데이터 사용 제어 제한을 편집할 수 있습니다.
+ 쿼리를 실행하면 현재 작업 그룹에서 실행됩니다. API 작업, 명령줄 인터페이스, JDBC 드라이버 또는 ODBC 드라이버를 사용하여 클라이언트 애플리케이션을 통해 콘솔의 작업 그룹 컨텍스트에서 쿼리를 실행할 수 있습니다.
+ Athena 콘솔 쿼리 편집기에서 각 작업 그룹 내에 쿼리 탭을 최대 10개까지 열 수 있습니다. 작업 그룹 간에 전환할 경우 쿼리 탭에는 최대 3개의 작업 그룹이 열린 채로 유지됩니다.
+ 계정에서 AWS 리전당 최대 1,000개의 작업 그룹을 생성할 수 있습니다.
+ 작업 그룹을 비활성화할 수 있습니다. 작업 그룹을 비활성화하면 다시 활성화할 때까지는 해당 작업 그룹에서 쿼리를 실행할 수 없습니다.
+ Athena는 저장된 쿼리가 포함된 작업 그룹을 삭제하려고 하면 경고를 표시합니다. 다른 사용자가 액세스할 수 있는 작업 그룹을 삭제하기 전에 해당 사용자가 다른 작업 그룹에 대해 쿼리를 실행하는 데 사용할 수 있는 액세스 권한이 있는지 확인하세요.

**Topics**
+ [고려 사항 및 제한 사항](#workgroups-considerations-limitations)
+ [작업 그룹 만들기](creating-workgroups.md)
+ [작업 그룹 관리](workgroups-create-update-delete.md)
+ [CloudWatch 및 EventBridge를 사용하여 쿼리 모니터링](workgroups-control-limits.md)
+ [Athena 작업 그룹 API 사용](workgroups-api-list.md)
+ [작업 그룹 문제 해결](workgroups-troubleshooting.md)

# 작업 그룹 만들기
<a name="creating-workgroups"></a>

작업 그룹을 만들려면 `CreateWorkgroup` API 작업에 대한 권한이 필요합니다. [작업 그룹 및 태그에 대한 액세스 구성](workgroups-access.md) 및 [IAM 정책을 사용하여 작업 그룹 액세스 제어](workgroups-iam-policy.md) 섹션을 참조하세요. 태그를 추가할 경우 `TagResource`에 대한 권한도 추가해야 합니다. [작업 그룹에 대한 태그 정책 예제](tags-access-control.md#tag-policy-examples-workgroups)을(를) 참조하세요.

다음 절차는 Athena 콘솔을 사용하여 작업 그룹을 생성하는 방법을 보여줍니다. Athena API를 사용하여 작업 그룹을 생성하려면 [CreateWorkGroup](https://docs.aws.amazon.com/athena/latest/APIReference/API_CreateWorkGroup.html)을 참조하세요.

**Athena 콘솔에서 작업 그룹을 생성하려면**

1.  생성할 작업 그룹을 결정합니다. 몇 가지 고려해야 할 요소는 다음과 같습니다.
   + 각 작업 그룹에서 쿼리를 실행할 수 있는 사용자 및 작업 구성을 소유하는 사용자. IAM 정책을 사용하여 작업 그룹 권한을 적용합니다. 자세한 내용은 [IAM 정책을 사용하여 작업 그룹 액세스 제어](workgroups-iam-policy.md) 섹션을 참조하세요.
   + Amazon S3에서 작업 그룹의 쿼리 결과에 사용할 위치. 작업 그룹의 모든 사용자가 이 위치에 액세스할 수 있어야 합니다.
   + 작업 그룹 쿼리 결과를 암호화해야 하는지 여부. 암호화는 쿼리별이 아니라 작업 그룹별로 수행되므로 암호화된 쿼리 결과와 암호화되지 않은 쿼리 결과에 대해 별도의 작업 그룹을 생성해야 합니다. 자세한 내용은 [Amazon S3에 저장된 Athena 쿼리 결과 암호화](encrypting-query-results-stored-in-s3.md) 섹션을 참조하세요.

1. 콘솔 탐색 창이 표시되지 않으면 왼쪽의 확장 메뉴를 선택합니다.  
![\[확장 메뉴를 선택합니다.\]](http://docs.aws.amazon.com/ko_kr/athena/latest/ug/images/nav-pane-expansion.png)

1. Athena 콘솔 탐색 창에서 **작업 그룹(Workgroups)**을 선택합니다.

1. **작업 그룹** 페이지에서 **작업 그룹 생성**을 선택합니다.

1. **작업 그룹 생성(Create workgroup)** 페이지에서 다음과 같이 필드에 값을 입력합니다.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/athena/latest/ug/creating-workgroups.html)

1. **작업 그룹 생성**을 선택합니다. **작업 그룹(Workgroups)** 페이지의 목록에 해당 작업 그룹이 나타납니다.

   쿼리 편집기에서 Athena는 콘솔 오른쪽 상단의 **작업 그룹** 옵션에 현재 작업 그룹을 표시합니다. 이 옵션을 사용하여 작업 그룹을 전환할 수 있습니다. 쿼리를 실행하면 현재 작업 그룹에서 실행됩니다.

1. 사용자 그룹 또는 역할에 대해 작업 그룹에 대한 액세스를 허용하는 IAM 정책을 생성합니다. 이 정책은 작업 그룹 멤버십과 `workgroup` 리소스에 대한 작업에 대한 액세스를 설정합니다. 자세한 내용은 [IAM 정책을 사용하여 작업 그룹 액세스 제어](workgroups-iam-policy.md) 섹션을 참조하세요. JSON 정책 예제는 [작업 그룹 및 태그에 대한 액세스 구성](workgroups-access.md) 단원을 참조하세요.

1. (선택 사항) 클라이언트 측 설정 재정의 옵션 때문에 작업 그룹 전체 암호화가 적용되지 않는 경우 Amazon S3에서 작업 그룹의 모든 쿼리 결과에 대해 최소 수준의 암호화를 구성합니다. 이 기능을 사용하면 쿼리 결과가 암호화되지 않은 상태로 Amazon S3 버킷에 저장되지 않도록 합니다. 자세한 내용은 [작업 그룹에 대한 최소 암호화 구성](workgroups-minimum-encryption.md) 섹션을 참조하세요.

1. (선택 사항) Amazon CloudWatch 및 Amazon EventBridge를 사용하여 작업 그룹의 쿼리를 모니터링하고 비용을 제어할 수 있습니다. 자세한 내용은 [CloudWatch 및 EventBridge를 사용하여 쿼리 모니터링 및 비용 제어](workgroups-control-limits.md) 섹션을 참조하세요.

1. (선택 사항) Billing and Cost Management 콘솔을 사용하여 작업 그룹에 비용 할당 태그를 지정합니다. 자세한 내용은 *AWS Billing 사용 설명서*에서 [사용자 정의 비용 할당 태그 사용](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/custom-tags.html)을 참조하세요.

1. (선택 사항) 작업 그룹에서 쿼리 전용 처리 용량을 확보하려면 작업 그룹을 용량 예약에 추가합니다. 하나 이상의 작업 그룹을 예약에 할당할 수 있습니다. 자세한 내용은 [쿼리 처리 용량 관리](capacity-management.md) 섹션을 참조하세요.

# Override client-side settings(클라이언트 측 설정 재정의)
<a name="workgroups-settings-override"></a>

작업 그룹을 생성하거나 편집할 때 **클라이언트측 설정 재정의** 옵션을 선택할 수 있습니다. 이 옵션은 기본적으로 설정되어 있지 않습니다. 이 필드의 선택 여부에 따라 Athena는 다음을 수행합니다.
+ **클라이언트 측 설정 재정의**를 선택하지 않으면 작업 그룹 설정이 클라이언트 수준에서 적용되지 않습니다. 작업 그룹에 대해 클라이언트 측 설정 재정의 옵션이 선택되지 않으면 Athena는 이 작업 그룹에서 실행하는 모든 쿼리에 대해 클라이언트 설정(쿼리 결과 위치 설정, 예상되는 버킷 소유자, 암호화, 쿼리 결과 버킷에 쓴 객체 제어 포함)을 사용합니다. 각 사용자는 콘솔의 **설정** 메뉴에서 자체 설정을 지정할 수 있습니다. 클라이언트 측 설정이 설정되지 않은 경우 작업 그룹 전체 설정이 적용됩니다. AWS CLI, API 작업 또는 JDBC 드라이버와 ODBC 드라이버를 사용하여 클라이언트 측 설정을 재정의하지 않는 작업 그룹에서 쿼리를 실행하는 경우 쿼리는 쿼리에 지정된 설정을 사용합니다.
+ **클라이언트 측 설정 재정의**를 선택하면 작업 그룹 설정이 작업 그룹의 모든 클라이언트에 대해 작업 그룹 수준에서 적용됩니다. 작업 그룹에 대해 클라이언트 측 설정 재정의 옵션이 선택되면 Athena는 이 작업 그룹에서 실행하는 모든 쿼리에 대해 작업 그룹 설정(쿼리 결과 위치 설정, 예상되는 버킷 소유자, 암호화, 쿼리 결과 버킷에 쓴 객체 제어 포함)을 사용합니다. 작업 그룹 설정은 콘솔, API 작업 또는 JDBC 드라이버나 ODBC 드라이버를 사용할 때 쿼리에 지정하는 모든 클라이언트 측 설정을 재정의합니다. 클라이언트 측 설정을 재정의하도록 작업 그룹을 설정한 후 드라이버 또는 API에서 클라이언트 측 설정을 생략할 수 있습니다.

  클라이언트 측 설정을 재정의하는 경우 다음에 사용자 또는 작업 그룹 사용자가 Athena 콘솔을 열 때 Athena는 작업 그룹의 쿼리가 작업 그룹의 설정을 사용함을 알리고 이 변경 사항을 승인하라는 메시지를 표시합니다.
**참고**  
클라이언트 측 설정을 재정의하면 임의의 Amazon S3 버킷의 결과 가용성을 기반으로 하는 사용자 지정 자동화가 중단될 수 있으므로 재정의하기 전에 최종 사용자에게 알리는 것이 좋습니다.
**중요**  
API 작업, AWS CLI 또는 JDBC 드라이버와 ODBC 드라이버를 사용하여 클라이언트 측 설정을 재정의하는 작업 그룹에서 쿼리를 실행하는 경우 쿼리에서 클라이언트 측 설정을 생략하거나 작업 그룹 설정에 맞게 업데이트해야 합니다.  
쿼리에서 클라이언트 측 설정을 지정하지만 설정을 재정의하는 작업 그룹에서 실행하면 쿼리는 실행되지만 작업 그룹 설정이 사용됩니다. 작업 그룹 설정 보기에 대한 자세한 내용은 [작업 그룹의 세부 정보 보기](viewing-details-workgroups.md) 섹션을 참조하세요.

# 작업 그룹 관리
<a name="workgroups-create-update-delete"></a>

Athena 콘솔([https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home))에서 다음 작업을 수행할 수 있습니다.




| 문 | 설명 | 
| --- | --- | 
|  [작업 그룹 만들기](creating-workgroups.md)  |  새로운 작업 그룹을 만듭니다.  | 
| [작업 그룹의 세부 정보 보기](viewing-details-workgroups.md) | 이름, 설명, 데이터 사용 제한, 쿼리 결과 위치, 예상 쿼리 결과 버킷 소유자 및 암호화와 같은 작업 그룹의 세부 정보를 봅니다. Override client-side settings(클라이언트 측 설정 재정의)를 선택한 경우 이 작업 그룹에서 해당 설정을 강제 적용할지 여부를 지정할 수도 있습니다. | 
|  [쿼리용 작업 그룹 지정](specify-wkgroup-to-athena-in-which-to-run-queries.md)  |  쿼리를 실행하려면 먼저 Athena에서 사용할 작업 그룹을 지정해야 합니다. 작업 그룹에 대해 사용 권한이 있어야 합니다.  | 
|  [작업 그룹 전환](switching-workgroups.md)  |  액세스 권한을 가진 작업 그룹 간에 전환합니다.  | 
|  [작업 그룹 편집](editing-workgroups.md)  | 작업 그룹을 편집하고 설정을 편집합니다. 작업 그룹의 이름은 변경할 수 없지만 동일한 설정으로 다른 이름을 사용하여 새 작업 그룹을 만들 수 있습니다. | 
|  [작업 그룹 활성화 또는 비활성화](workgroups-enabled-disabled.md)  |  작업 그룹을 활성화거나 비활성화합니다. 작업 그룹이 비활성화된 경우 사용자가 쿼리를 실행하거나 새로운 이름 지정 쿼리를 만들 수 없습니다. 액세스 권한이 있는 경우 지표, 데이터 사용량 한도 제어, 작업 그룹의 설정, 쿼리 기록 및 저장된 쿼리는 계속 볼 수 있습니다.  | 
|  [작업 그룹 간에 저장된 쿼리 복사](copy-a-query-between-workgroups.md)  | 작업 그룹 간에 저장된 쿼리를 복사합니다. 예를 들어 미리 보기 작업 그룹에서 쿼리를 생성했는데 미리 보기가 아닌 작업 그룹에서도 사용하도록 하려 할 경우에 이 기능이 필요할 수 있습니다. | 
|  [작업 그룹 삭제](deleting-workgroups.md)  |  작업 그룹을 삭제합니다. 작업 그룹을 삭제할 경우 쿼리 기록, 저장된 쿼리, 작업 그룹의 설정, 쿼리당 데이터 한도 제어 등도 삭제됩니다. 작업 그룹 전역의 데이터 한도 제어는 CloudWatch에서 유지되며 개별적으로 삭제할 수 있습니다. 기본 작업 그룹은 삭제할 수 없습니다.  | 
| [IAM 정책을 사용하여 작업 그룹 액세스 제어](workgroups-iam-policy.md) | IAM 정책을 사용하여 작업 그룹 액세스를 제어합니다. 작업 그룹 정책 예제는 [작업 그룹 정책 예제](example-policies-workgroup.md) 섹션을 참조하세요. | 
| [IAM Identity Center 인증을 사용하는 Athena 작업 그룹 생성](workgroups-identity-center.md) | Athena에서 IAM Identity Center ID를 사용하려면 IAM Identity Center 지원 작업 그룹을 생성해야 합니다. 작업 그룹을 생성한 후 IAM Identity Center 콘솔 또는 API를 사용하여 작업 그룹에 IAM Identity Center 사용자 또는 그룹을 할당할 수 있습니다. | 
| [작업 그룹에 대한 최소 암호화 구성](workgroups-minimum-encryption.md) | Amazon S3에서 작업 그룹의 모든 쿼리 결과에 대해 최소 수준의 암호화를 적용합니다. 이 기능을 사용하여 쿼리 결과가 암호화되지 않은 상태로 Amazon S3 버킷에 저장되지 않도록 합니다. | 

# 작업 그룹의 세부 정보 보기
<a name="viewing-details-workgroups"></a>

각 작업 그룹에 대해 해당 세부 정보를 볼 수 있습니다. 세부 정보에는 작업 그룹의 이름, 설명, 사용 설정 또는 사용 중지 여부 및 작업 그룹에서 실행되는 쿼리에 사용되는 설정(쿼리 결과 위치 및 암호화 구성 등)이 표시됩니다. 작업 그룹에 데이터 사용 한도가 있을 경우 이 설정도 표시됩니다.

**작업 그룹의 세부 정보를 보려면**

1. Athena 콘솔 탐색 창에서 **작업 그룹(Workgroups)**을 선택합니다.

1. **작업 그룹(Workgroups)** 페이지에서 보려는 작업 그룹의 링크를 선택합니다. 작업 그룹에 대한 **개요 세부 정보(Overview Details)** 페이지가 표시됩니다.

# 쿼리용 작업 그룹 지정
<a name="specify-wkgroup-to-athena-in-which-to-run-queries"></a>

사용할 작업 그룹을 지정하려면 작업 그룹에 대한 권한이 있어야 합니다.

**사용할 작업 그룹 지정**

1. 사용하려는 작업 그룹에서 쿼리를 실행할 수 있는 권한이 있는지 확인합니다. 자세한 내용은 [IAM 정책을 사용하여 작업 그룹 액세스 제어](workgroups-iam-policy.md) 섹션을 참조하세요.

1.  작업 그룹을 지정하려면 다음 옵션 중 하나를 사용합니다.
   + Athena 콘솔을 사용하는 경우 [작업 그룹을 전환](switching-workgroups.md)하여 작업 그룹을 설정합니다.
   + Athena API 작업을 사용할 경우 API 작업에 작업 그룹 이름을 지정합니다. 예를 들어 다음과 같이 [StartQueryExecution](https://docs.aws.amazon.com/athena/latest/APIReference/API_StartQueryExecution.html)에 작업 그룹 이름을 설정할 수 있습니다.

     ```
     StartQueryExecutionRequest startQueryExecutionRequest = new StartQueryExecutionRequest()
                   .withQueryString(ExampleConstants.ATHENA_SAMPLE_QUERY)
                   .withQueryExecutionContext(queryExecutionContext)
                   .withWorkGroup(WorkgroupName)
     ```
   + JDBC 또는 ODBC 드라이버를 사용할 경우 `Workgroup` 구성 파라미터를 사용하여 연결 문자열에 작업 그룹 이름을 설정합니다. 드라이버는 작업 그룹 이름을 Athena에 전달합니다. 다음 예제에서와 같이 연결 문자열에 작업 그룹 파라미터를 지정합니다.

     ```
     jdbc:awsathena://AwsRegion=<AWSREGION>;UID=<ACCESSKEY>;
     PWD=<SECRETKEY>;S3OutputLocation=s3://amzn-s3-demo-bucket/<athena-output>-<AWSREGION>/;
     Workgroup=<WORKGROUPNAME>;
     ```

# 작업 그룹 전환
<a name="switching-workgroups"></a>

작업 그룹에 대해 권한이 있을 경우 한 작업 그룹에서 다른 작업 그룹으로 전환할 수 있습니다.

각 작업 그룹에서 쿼리 탭을 10개까지 열 수 있습니다. 작업 그룹 간에 전환할 경우 쿼리 탭은 최대 3개의 작업 그룹에 대해 열린 채로 유지됩니다.

**작업 그룹 전환**

1. Athena 콘솔에서 오른쪽 상단의 **작업 그룹(Workgroup)** 옵션을 사용하여 작업 그룹을 선택합니다.

1. **작업 그룹 *workgroup-name* 설정(Workgroup workgroup-name settings)** 대화 상자가 나타나면 **승인(Acknowledge)**을 선택합니다.

**작업 그룹(Workgroup)** 옵션은 전환한 작업 그룹의 이름을 표시합니다. 이제 이 작업 그룹에서 쿼리를 실행할 수 있습니다.

# 작업 그룹 편집
<a name="editing-workgroups"></a>

작업 그룹을 편집하려면 `UpdateWorkgroup` API 작업에 대한 권한이 필요합니다. [작업 그룹 및 태그에 대한 액세스 구성](workgroups-access.md) 및 [IAM 정책을 사용하여 작업 그룹 액세스 제어](workgroups-iam-policy.md) 섹션을 참조하세요. 태그를 추가하거나 편집할 경우 `TagResource`에 대한 권한도 있어야 합니다. [작업 그룹에 대한 태그 정책 예제](tags-access-control.md#tag-policy-examples-workgroups)을(를) 참조하세요.

**콘솔에서 작업 그룹을 편집하려면**

1. Athena 콘솔 탐색 창에서 **작업 그룹(Workgroups)**을 선택합니다.

1. **작업 그룹(Workgroups)** 페이지에서 편집할 작업 그룹의 버튼을 선택합니다.

1. **작업(Actions)**, **편집(Edit)**을 선택합니다.

1. 필요 시 이 필드를 변경합니다. 필드 목록을 보려면 [작업 그룹 생성](creating-workgroups.md)을 참조하세요. 작업 그룹 이름을 제외한 모든 필드를 변경할 수 있습니다. 이름을 변경해야 할 경우, 동일한 설정으로 작업 그룹을 만든 후 새 이름을 지정하세요.

1. **변경 사항 저장**을 선택합니다. **작업 그룹(Workgroups)** 페이지의 목록에 업데이트된 작업 그룹이 나타납니다.

# 작업 그룹 활성화 또는 비활성화
<a name="workgroups-enabled-disabled"></a>

권한이 있는 경우 콘솔에서 또는 API 작업이나 JDBC 및 ODBC 드라이버를 사용하여 작업 그룹을 활성화하거나 비활성화할 수 있습니다.

**작업 그룹을 활성화거나 비활성화하려면**

1. Athena 콘솔 탐색 창에서 **작업 그룹(Workgroups)**을 선택합니다.

1. **작업 그룹(Workgroups)** 페이지에서 작업 그룹의 링크를 선택합니다.

1. 오른쪽 상단에서 **작업 그룹 활성화(Enable workgroup)** 또는 **작업 그룹 비활성화(Disable workgroup)**를 선택합니다.

1. 확인 프롬프트에서 **활성화(Enable)** 또는 **비활성화(Disable)**를 선택합니다. 작업 그룹을 비활성화한 경우 해당 작업 그룹의 사용자는 그 작업 그룹에서 쿼리를 실행하거나 새로운 이름 지정 쿼리를 만들 수 없습니다. 작업 그룹을 활성화한 경우, 사용자는 해당 작업 그룹을 사용하여 쿼리를 실행할 수 있습니다.

# 작업 그룹 간에 저장된 쿼리 복사
<a name="copy-a-query-between-workgroups"></a>

현재 Athena 콘솔에는 저장된 쿼리를 한 작업 그룹에서 다른 작업 그룹으로 직접 복사할 수 있는 옵션이 없지만 다음 절차를 사용하여 수동으로 동일한 작업을 수행할 수 있습니다.

**작업 그룹 간에 저장된 쿼리를 복사하려면**

1. Athena 콘솔에서, 쿼리를 복사해 올 작업 그룹에서 **저장된 쿼리(Saved queries)** 탭을 클릭합니다.

1. 복사하려는 저장된 쿼리의 링크를 선택합니다. Athena는 쿼리 편집기에서 쿼리를 엽니다.

1. 쿼리 편집기에서 쿼리 텍스트를 선택한 후 **Ctrl\$1C**를 눌러 복사합니다.

1. 대상 작업 그룹으로 [전환](switching-workgroups.md)하거나, [작업 그룹을 생성](creating-workgroups.md)한 다음 대상 작업 그룹으로 전환합니다.

1. 쿼리 편집기에서 새 탭을 연 다음 **Ctrl\$1V**를 눌러 텍스트를 새 탭에 붙여 넣습니다.

1. 쿼리 편집기에서 **다른 이름으로 저장(Save as)**을 클릭하여 대상 작업 그룹에 쿼리를 저장합니다.

1. **이름 선택(Choose a name)** 대화 상자에서 쿼리의 이름과 설명(선택 사항)을 입력합니다.

1. **저장**을 선택합니다.

# 작업 그룹 삭제
<a name="deleting-workgroups"></a>

작업 그룹 삭제 권한이 있으면 작업 그룹을 삭제할 수 있습니다. 기본 작업 그룹은 삭제할 수 없습니다.

권한이 있는 경우 언제든 빈 작업 그룹을 삭제할 수 있습니다. 저장된 쿼리가 들어 있는 작업 그룹도 삭제할 수 있습니다. 이 경우 작업 그룹 삭제를 진행하기 전에 Athena가 저장된 쿼리의 삭제를 경고합니다.

작업 그룹 내에서 작업 그룹을 삭제할 경우 콘솔에서 기본 작업 그룹으로 포커스가 전환됩니다. 해당 작업 그룹에 대해 액세스 권한이 있을 경우 쿼리를 실행하고 해당 설정을 볼 수 있습니다.

작업 그룹을 삭제할 경우 작업 그룹의 설정 및 쿼리당 데이터 한도 제어가 삭제됩니다. 작업 그룹 전역의 데이터 한도 제어는 CloudWatch에서 유지되며 필요할 경우 삭제할 수 있습니다.

**중요**  
작업 그룹을 삭제하기 전에 작업 그룹의 사용자가 쿼리 실행을 계속할 수 있는 다른 작업 그룹에 속해 있는지 확인해야 합니다. 사용자의 IAM 정책에서 사용자에게 *오직* 이 작업 그룹에서만 쿼리를 실행하도록 허용한 경우 이 작업 그룹을 삭제하면 해당 사용자는 더 이상 쿼리를 실행할 수 있는 권한이 없어집니다. 자세한 내용은 [Example policy for running queries in the primary workgroup](example-policies-workgroup.md#example4-run-in-primary-access) 단원을 참조하세요.

**콘솔에서 작업 그룹을 삭제하려면**

1. Athena 콘솔 탐색 창에서 **작업 그룹(Workgroups)**을 선택합니다.

1. **작업 그룹(Workgroups)** 페이지에서 삭제할 작업 그룹의 버튼을 선택합니다.

1. **작업**, **삭제**를 선택합니다.

1. **작업 그룹 삭제(Delete workgroup)** 확인 프롬프트에서 작업 그룹의 이름을 입력한 다음 **삭제(Delete)**를 선택합니다.

API 작업을 사용하여 작업 그룹을 삭제하려면 `DeleteWorkGroup` 작업을 사용합니다.

# CloudWatch 및 EventBridge를 사용하여 쿼리 모니터링 및 비용 제어
<a name="workgroups-control-limits"></a>

작업 그룹에서는 쿼리당 또는 작업 그룹당 데이터 사용량 제어 한도를 설정하고, 이러한 한도가 초과될 때 경보를 설정할 수 있으며, CloudWatch에 쿼리 지표를 게시할 수 있습니다.

각 작업 그룹에서 다음을 수행할 수 있습니다.
+ 쿼리당 그리고 작업 그룹당 **데이터 사용량 제어**를 구성하고, 쿼리가 임계값을 위반할 경우 수행할 작업을 설정합니다.
+ 쿼리 지표를 보고 분석하며 CloudWatch에 게시합니다. 콘솔에서 작업그룹을 만들 경우 CloudWatch에 지표를 게시하는 설정이 자동으로 선택됩니다. API 작업을 사용할 경우 [지표 게시를 활성화](athena-cloudwatch-metrics-enable.md)해야 합니다. 지표가 게시되면 **작업 그룹** 패널의 **지표** 탭 아래에 표시됩니다. 지표는 기본 작업 그룹에 대해 기본적으로 비활성화됩니다.

## 비디오
<a name="athena-cloudwatch-metrics-video"></a>

다음 동영상은 CloudWatch에서 사용자 지정 대시보드를 생성하고 지표에 대한 경보 및 트리거를 설정하는 방법을 보여 줍니다. Athena 콘솔에서 사전 입력된 대시보드를 직접 사용해 이러한 쿼리 지표를 이용할 수 있습니다.

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


**Topics**
+ [비디오](#athena-cloudwatch-metrics-video)
+ [쿼리 지표 활성화](athena-cloudwatch-metrics-enable.md)
+ [CloudWatch를 사용하여 쿼리 지표 모니터링](query-metrics-viewing.md)
+ [CloudWatch를 사용하여 사용량 지표 모니터링](monitoring-athena-usage-metrics.md)
+ [EventBridge를 사용하여 쿼리 이벤트 모니터링](athena-events.md)
+ [데이터 사용량 제어 구성](workgroups-setting-control-limits-cloudwatch.md)

# Athena에서 CloudWatch 쿼리 지표 활성화
<a name="athena-cloudwatch-metrics-enable"></a>

콘솔에서 작업그룹을 만들 경우 CloudWatch에 쿼리 지표를 게시하는 설정이 기본적으로 선택됩니다.

**Athena 콘솔에서 작업 그룹에 대해 쿼리 지표를 활성화 또는 비활성화하려면**

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 콘솔 탐색 창이 표시되지 않으면 왼쪽의 확장 메뉴를 선택합니다.  
![\[확장 메뉴를 선택합니다.\]](http://docs.aws.amazon.com/ko_kr/athena/latest/ug/images/nav-pane-expansion.png)

1. 탐색 창에서 **작업 그룹(Workgroups)**을 선택합니다.

1. 수정할 작업 그룹의 링크를 선택합니다.

1. 작업 그룹에 대한 세부 정보 페이지에서 **편집(Edit)**을 선택합니다.

1. **설정(Settings)** 섹션에서 **AWS CloudWatch에 쿼리 지표 게시(Publish query metrics to CloudWatch)**를 선택하거나 선택 취소합니다.

API 작업, 명령줄 인터페이스 또는 JDBC 드라이버가 있는 클라이언트 애플리케이션을 사용하여 작업 그룹을 생성하고 쿼리 지표 게시를 활성화하는 경우 [WorkGroupConfiguration](https://docs.aws.amazon.com/athena/latest/APIReference/API_WorkGroupConfiguration.html)에서 `PublishCloudWatchMetricsEnabled`를 `true`로 설정합니다. 다음 예제는 지표 구성만 보여 주고 다른 구성은 생략합니다.

```
"WorkGroupConfiguration": { 
      "PublishCloudWatchMetricsEnabled": "true"
     ....
     }
```

# CloudWatch를 사용하여 Athena 쿼리 지표 모니터링
<a name="query-metrics-viewing"></a>

[CloudWatch에 쿼리 지표 게시](athena-cloudwatch-metrics-enable.md) 옵션을 선택하면 Athena는 쿼리 관련 지표를 Amazon CloudWatch에 게시합니다. 사용자 지정 대시보드를 만들거나, CloudWatch의 지표에 대해 경보 및 트리거를 설정하거나, Athena 콘솔에서 사전 입력된 대시보드를 직접 사용할 수 있습니다.

작업 그룹의 쿼리에 대해 쿼리 지표를 활성화하면 Athena 콘솔에서 각 작업 그룹에 대한 **작업 그룹** 패널의 **지표** 탭에 지표가 표시됩니다.

Athena는 다음의 지표를 CloudWatch 콘솔에 게시합니다.
+ `DPUAllocated` - 쿼리를 실행하기 위해 용량 예약에 프로비저닝된 총 데이터 처리 단위(DPU) 수입니다.
+ `DPUConsumed` - 예약에서 특정 시간에 `RUNNING` 상태의 쿼리가 소비하는 DPU 수입니다. 작업 그룹이 용량 예약과 연결되어 있고 예약과 연결된 모든 작업 그룹을 포함하는 경우에만 생성되는 지표입니다.
+ `DPUCount` - 쿼리가 소비하는 최대 DPU 수로, 쿼리가 완료될 때 정확히 한 번 게시됩니다.
+ `EngineExecutionTime` - 쿼리를 실행하는 데 걸린 시간(밀리초)입니다.
+ `ProcessedBytes` - DML 쿼리당 Athena가 스캔한 바이트 수입니다.
+ `QueryPlanningTime` - Athena가 쿼리 처리 흐름을 계획하는 데 걸린 시간(밀리초)입니다.
+ `QueryQueueTime` - 쿼리가 리소스를 기다리면서 쿼리 대기열에 있던 시간(밀리초)입니다.
+ `ServicePreProcessingTime` - Athena가 쿼리 엔진에 쿼리를 제출하기 전에 쿼리를 사전 처리하는 데 걸린 시간(밀리초)입니다.
+ `ServiceProcessingTime` - 쿼리 엔진이 쿼리 실행을 완료한 후 Athena가 쿼리 결과를 처리하는 데 걸린 시간(밀리초)입니다.
+ `TotalExecutionTime` - Athena가 DDL 또는 DML 쿼리를 실행하는 데 걸린 시간(밀리초)입니다.

자세한 설명은 이 문서 뒷부분의 [Athena의 CloudWatch 지표 및 차원 목록](#athena-cloudwatch-metrics-table) 섹션을 참조하세요.

이러한 지표에는 다음과 같은 차원이 있습니다.
+ `CapacityReservation` - 해당하는 경우 쿼리를 실행하는 데 사용된 용량 예약의 이름입니다.
+ `QueryState` - `SUCCEEDED`, `FAILED` 또는 `CANCELED`
+ `QueryType` - `DML`, `DDL` 또는 `UTILITY`
+ `WorkGroup` - 작업 그룹의 이름입니다.

Athena는 다음의 지표를 `AmazonAthenaForApacheSpark` 네임스페이스 아래 CloudWatch 콘솔에 게시합니다.
+ `DPUCount` - 세션 중에 계산을 실행하는 데 사용된 DPU 수입니다.

이 지표에는 다음과 같은 차원이 있습니다.
+ `SessionId` - 계산이 제출되는 세션의 ID입니다.
+ `WorkGroup` - 작업 그룹의 이름입니다.

자세한 내용은 이 주제의 후반부에서 [Athena의 CloudWatch 지표 및 차원 목록](#athena-cloudwatch-metrics-table) 단원을 참조하세요. Athena 사용량 지표에 대한 자세한 내용은 [CloudWatch를 사용하여 Athena 사용량 지표 모니터링](monitoring-athena-usage-metrics.md) 섹션을 참조하세요.

Athena 콘솔 또는 CloudWatch 콘솔에서 쿼리 지표를 볼 수 있습니다.

## Athena 콘솔에서 쿼리 지표 보기
<a name="query-metrics-viewing-athena-console"></a>

**Athena 콘솔에서 작업 그룹에 대한 쿼리 지표를 보려면**

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 콘솔 탐색 창이 표시되지 않으면 왼쪽의 확장 메뉴를 선택합니다.  
![\[확장 메뉴를 선택합니다.\]](http://docs.aws.amazon.com/ko_kr/athena/latest/ug/images/nav-pane-expansion.png)

1. 탐색 창에서 **작업 그룹(Workgroups)**을 선택합니다.

1. 목록에서 원하는 작업 그룹을 선택한 다음 **지표(Metrics)** 탭을 선택합니다.

   지표 대시보드가 표시됩니다.
**참고**  
작업 그룹에 대한 지표를 최근에 활성화했거나 최근 쿼리 활동이 없었다면 대시보드의 그래프가 비어 있을 수 있습니다. 다음 단계에서 지정하는 간격마다 CloudWatch에서 쿼리 활동을 검색합니다.

1. **지표(Metrics)** 섹션에서 Athena가 CloudWatch에서 쿼리 활동을 가져오는 데 사용할 지표 간격을 선택하거나, 사용자 지정 간격을 지정합니다.  
![\[Athena 콘솔에서 작업 그룹에 대한 지표 검색 간격 지정.\]](http://docs.aws.amazon.com/ko_kr/athena/latest/ug/images/wg-custom-interval.png)

1. 표시된 지표를 새로 고치려면 새로 고침 아이콘을 선택합니다.  
![\[새로 고침 아이콘을 선택합니다.\]](http://docs.aws.amazon.com/ko_kr/athena/latest/ug/images/wg-refresh-metrics.png)

1. 새로 고침 아이콘 옆에 있는 화살표를 클릭하여 지표 표시를 업데이트할 빈도를 선택합니다.  
![\[Athena 콘솔에서 작업 그룹 지표를 표시하기 위한 새로 고침 간격 선택.\]](http://docs.aws.amazon.com/ko_kr/athena/latest/ug/images/wg-choose-refresh-interval.png)

## CloudWatch 콘솔에서 쿼리 지표 보기
<a name="query-metrics-viewing-cw-console"></a>

**Amazon CloudWatch 콘솔에서 지표를 보려면**

1. [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)에서 CloudWatch 콘솔을 엽니다.

1. 탐색 창에서 **지표**, **모든 지표**를 선택합니다.

1. **AWS/Athena** 네임스페이스를 선택합니다.

## AWS CLI를 사용하여 쿼리 지표 보기
<a name="query-metrics-viewing-cli"></a>

**AWS CLI를 사용하여 지표를 보려면**
+ 다음 중 하나를 수행하세요.
  + Athena에 대한 지표를 나열하려면 명령 프롬프트를 열고 다음 명령을 사용합니다.

    ```
    aws cloudwatch list-metrics --namespace "AWS/Athena"
    ```
  + 사용 가능한 모든 지표의 목록을 보려면 다음 명령을 사용합니다.

    ```
    aws cloudwatch list-metrics"
    ```

## Athena의 CloudWatch 지표 및 차원 목록
<a name="athena-cloudwatch-metrics-table"></a>

Athena에서 CloudWatch 지표를 활성화했다면 다음 지표가 작업 그룹별로 CloudWatch로 전송됩니다. 다음 지표에서 `AWS/Athena` 네임스페이스를 사용합니다.


| 지표 이름 | 설명 | 
| --- | --- | 
| DPUAllocated |  쿼리를 실행하기 위해 용량 예약에 프로비저닝된 총 데이터 처리 단위(DPU) 수입니다.  | 
| DPUConsumed | 예약에서 특정 시간에 RUNNING 상태의 쿼리가 소비하는 DPU 수입니다. 이 지표는 작업 그룹이 용량 예약과 연결되어 있고 예약과 연결된 모든 작업 그룹을 포함하는 경우에만 생성됩니다. 작업 그룹을 한 예약에서 다른 예약으로 이동하면 해당 작업 그룹이 첫 번째 예약에 속했던 시점의 데이터가 지표에 포함됩니다. 용량 예약에 대한 자세한 내용은 [쿼리 처리 용량 관리](capacity-management.md) 섹션을 참조하세요. | 
| DPUCount | 쿼리가 소비하는 최대 DPU 수로, 쿼리가 완료될 때 정확히 한 번 게시됩니다. 이 지표는 용량 예약에 연결된 작업 그룹에 대해서만 생성됩니다. | 
| EngineExecutionTime |  쿼리를 실행하는 데 걸린 시간(밀리초)입니다.  | 
| ProcessedBytes |  DML 쿼리당 Athena가 스캔한 바이트 수입니다. 취소된 쿼리의 경우(한도에 다다른 경우, 쿼리가 사용자에 의해 또는 자동으로 취소됨), 취소 시간 이전에 스캔한 데이터의 양을 포함합니다. DDL 쿼리에 대해서는 이 지표가 보고되지 않습니다.  | 
| QueryPlanningTime | Athena가 쿼리 처리 흐름을 계획하는 데 걸린 시간(밀리초)입니다. 여기에는 데이터 소스로부터 테이블 파티션을 검색하는 데 소요된 시간이 포함됩니다. 쿼리 엔진은 쿼리 계획을 수행하기 때문에 쿼리 계획 시간은 EngineExecutionTime의 하위 집합입니다. | 
| QueryQueueTime | 쿼리가 리소스를 기다리면서 쿼리 대기열에 있던 시간(밀리초) 입니다. 일시적인 오류가 발생하면 쿼리가 자동으로 대기열에 다시 추가될 수 있습니다. | 
| ServicePreProcessingTime | Athena가 쿼리 엔진에 쿼리를 제출하기 전에 쿼리를 사전 처리하는 데 걸린 시간(밀리초)입니다. | 
| ServiceProcessingTime | 쿼리 엔진이 쿼리 실행을 완료한 후 Athena가 쿼리 결과를 처리하는 데 걸린 시간(밀리초)입니다. | 
| TotalExecutionTime | Athena가 DDL 또는 DML 쿼리를 실행하는 데 걸린 시간(밀리초)입니다. TotalExecutionTime에는 QueryQueueTime, QueryPlanningTime, EngineExecutionTime 및 ServiceProcessingTime이 포함됩니다.. | 

Athena의 이 지표에는 다음과 같은 차원이 있습니다.


| 차원 | 설명 | 
| --- | --- | 
| CapacityReservation |  해당하는 경우 쿼리를 실행하는 데 사용된 용량 예약의 이름입니다. 용량 예약이 사용되지 않으면 이 차원은 데이터를 반환하지 않습니다.  | 
| QueryState |  쿼리 상태입니다. 유효한 통계: SUCCEEDED, FAILED 또는 CANCELED.  | 
| QueryType |  쿼리 유형입니다. 유효한 통계: `DDL`, `DML` 또는 `UTILITY`. 실행된 쿼리 문의 유형입니다. `DDL`은 데이터 정의 언어(DDL) 쿼리 문을 나타냅니다. `DML`은 데이터 조작 언어(DML) 쿼리 문을 나타냅니다(예: `CREATE TABLE AS SELECT`). `UTILITY`는 DDL 및 DML 이외의 쿼리 문(예:`SHOW CREATE TABLE` 또는 `DESCRIBE TABLE`)을 나타냅니다.  | 
| WorkGroup |  작업 그룹의 이름입니다.  | 

# CloudWatch를 사용하여 Athena 사용량 지표 모니터링
<a name="monitoring-athena-usage-metrics"></a>

CloudWatch 사용량 지표를 사용하여 CloudWatch 그래프 및 대시보드에서 현재 서비스 사용량을 표시하여 계정에서 리소스가 어떻게 사용되고 있는지 확인할 수 있습니다.

Athena의 경우 사용량 가용성 지표는 Athena의 AWS 서비스 할당량에 해당합니다. 사용량이 서비스 할당량에 가까워지면 경고하는 경보를 구성할 수 있습니다. Athena 서비스 할당량에 대한 자세한 내용은 [Service Quotas](service-limits.md) 섹션을 참조하세요. AWS 사용량 지표에 대한 자세한 내용은 *Amazon CloudWatch 사용 설명서*의 [AWS 사용량 지표](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Service-Quota-Integration.html)를 참조하세요.

Athena는 `AWS/Usage` 네임스페이스에 다음 지표를 게시합니다.


|  지표 이름  |  설명  | 
| --- | --- | 
|  `ResourceCount`  |  쿼리 유형(DML 또는 DDL)으로 구분된 계정당 AWS 리전에 따라 대기 중인 모든 쿼리와 실행 쿼리의 합계입니다. Maximum은 이 지표에 가장 유용한 통계입니다. 이 지표는 1분마다 주기적으로 게시됩니다. 쿼리를 실행하지 않는 경우 이 지표는 아무 것도 보고하지 않습니다(0도 보고하지 않음). 이 지표는 지표가 계산될 때 활성 쿼리가 실행 중인 경우에만 게시됩니다.  | 

다음 차원은 Athena에 의해 게시되는 사용량 지표를 구체화하는 데 사용됩니다.


|  차원  |  설명  | 
| --- | --- | 
|  `Service`  |  리소스가 포함된 AWS 서비스의 이름 Athena의 경우 이 차원의 값은 `Athena`입니다.  | 
|  `Resource`  |  실행 중인 리소스의 유형입니다. Athena 쿼리 사용량에 대한 리소스 값은 `ActiveQueryCount`입니다.  | 
|  `Type`  |  보고되는 엔터티의 유형입니다. 현재 Athena 사용량 지표에 대한 유일한 유효 값은 `Resource`입니다.  | 
|  `Class`  |  추적 중인 리소스의 클래스입니다. Athena의 경우, `Class`는 `DML` 또는 `DDL`이 될 수 있습니다.  | 

## CloudWatch 콘솔에서 Athena 리소스 사용량 지표 보기
<a name="monitoring-athena-usage-metrics-cw-console"></a>

CloudWatch 콘솔을 사용하여 Athena 사용량 지표의 그래프를 표시하고 사용량이 서비스 할당량에 가까워지면 경고하는 경보를 구성할 수 있습니다.

**Athena 리소스 사용량 지표를 보려면**

1. [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)에서 CloudWatch 콘솔을 엽니다.

1. 탐색 창에서 **지표**, **모든 지표**를 선택합니다.

1. **사용량**(Usage)을 선택한 다음 **AWS 리소스별**(By Resource)을 선택합니다.

   서비스 할당량 사용량 지표 목록이 나타납니다.

1. **Athena** 및 **ActiveQueryCount** 옆에 있는 확인란을 선택합니다.

1. **그래프로 표시된 지표** 탭을 선택합니다.

   위의 그래프는 AWS 리소스의 현재 사용량을 표시합니다.

그래프에 서비스 할당량을 추가하고 서비스 할당량에 가까워지면 알려주는 경보를 설정하는 데 대한 자세한 내용은 *Amazon CloudWatch 사용 설명서*에서 [서비스 할당량 시각화 및 경보 설정](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Quotas-Visualize-Alarms.html)을 참조하세요. 작업 그룹당 사용량 한도 설정에 대한 자세한 내용은 [쿼리당 및 작업 그룹당 데이터 사용량 제어 구성](workgroups-setting-control-limits-cloudwatch.md) 섹션을 참조하세요.

# EventBridge를 사용하여 Athena 쿼리 이벤트 모니터링
<a name="athena-events"></a>

Amazon EventBridge와 함께 Amazon Athena를 사용하여 쿼리 상태에 대한 실시간 알림을 받을 수 있습니다. 사용자가 제출한 쿼리의 상태가 전환되면 Athena는 해당 쿼리 상태 전환에 대한 정보를 포함하는 이벤트를 EventBridge에 게시합니다. 원하는 이벤트에 대한 간단한 규칙을 작성하고 규칙과 일치하는 이벤트 발생 시 자동으로 작업을 수행하도록 할 수 있습니다. 예를 들어 쿼리가 종료 상태에 도달할 때 AWS Lambda 함수를 호출하는 규칙을 만들 수 있습니다. 이벤트는 최선의 작업을 기반으로 발생됩니다.

Athena에 대한 이벤트 규칙을 생성하기 전에 다음을 수행해야 합니다.
+ Eventbridge의 이벤트, 규칙, 대상을 숙지해야 합니다. 자세한 내용은 [Amazon EventBridge란 무엇입니까?](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html)를 참조하십시오. 규칙을 설정하는 방법에 대한 자세한 내용은 [Amazon EventBridge 시작하기](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-get-started.html)를 참조하세요.
+ 이벤트 규칙에 사용할 대상을 만듭니다.

**참고**  
Athena는 현재 한 가지 유형의 이벤트인 Athena 쿼리 상태 변경을 제공하지만 다른 이벤트 유형 및 세부 정보를 추가할 수도 있습니다. 프로그래밍 방식으로 이벤트 JSON 데이터를 역직렬화하는 경우, 추가 속성이 추가되었을 때 알 수 없는 속성을 처리할 수 있도록 애플리케이션이 준비되어야 합니다.

## Athena 이벤트 형식
<a name="athena-events-pattern"></a>

다음은 Amazon Athena 이벤트의 기본 패턴입니다.

```
{
    "source":[
        "aws.athena"
    ],
    "detail-type":[
        "Athena Query State Change"
    ],
    "detail":{
        "currentState":[
            "SUCCEEDED"
        ]
    }
}
```

## Athena 쿼리 상태 변경 이벤트
<a name="athena-events-athena-query-state-change"></a>

다음 예제에서는 `currentState` 값이 `SUCCEEDED`인 Athena 쿼리 상태 변경 이벤트를 보여 줍니다.

```
{
    "version":"0",
    "id":"abcdef00-1234-5678-9abc-def012345678",
    "detail-type":"Athena Query State Change",
    "source":"aws.athena",
    "account":"123456789012",
    "time":"2019-10-06T09:30:10Z",
    "region":"us-east-1",
    "resources":[

    ],
    "detail":{
        "versionId":"0",
        "currentState":"SUCCEEDED",
        "previousState":"RUNNING",
        "statementType":"DDL",
        "queryExecutionId":"01234567-0123-0123-0123-012345678901",
        "workgroupName":"primary",
        "sequenceNumber":"3"
    }
}
```

다음 예제에서는 `currentState` 값이 `FAILED`인 Athena 쿼리 상태 변경 이벤트를 보여 줍니다. `athenaError` 블록은 `currentState`가 `FAILED`인 경우에만 나타납니다. `errorCategory` 및 `errorType`에 대한 값 관련 내용은 [Athena 오류 카탈로그](error-reference.md) 단원을 참조하세요.

```
{
    "version":"0",
    "id":"abcdef00-1234-5678-9abc-def012345678",
    "detail-type":"Athena Query State Change",
    "source":"aws.athena",
    "account":"123456789012",
    "time":"2019-10-06T09:30:10Z",
    "region":"us-east-1",
    "resources":[ 
    ],
    "detail":{
        "athenaError": {
            "errorCategory": 2.0, //Value depends on nature of exception
            "errorType": 1306.0, //Type depends on nature of exception
            "errorMessage": "Amazon S3 bucket not found", //Message depends on nature of exception
            "retryable":false //Retryable value depends on nature of exception
        },
        "versionId":"0",
        "currentState": "FAILED",
        "previousState": "RUNNING",
        "statementType":"DML",
        "queryExecutionId":"01234567-0123-0123-0123-012345678901",
        "workgroupName":"primary",
        "sequenceNumber":"3"
    }
}
```

### 출력 속성
<a name="athena-events-query-state-change-output-properties"></a>

JSON 출력에는 다음 속성이 포함됩니다.


****  

| 속성 | 설명 | 
| --- | --- | 
| athenaError | currentState가 FAILED인 경우에만 나타납니다. 오류 범주, 오류 유형, 오류 메시지, 오류를 일으킨 작업을 재시도할 수 있는지 여부 등 발생한 오류에 대한 정보가 포함되어 있습니다. 이러한 각 필드의 값은 오류의 특성에 따라 달라집니다. errorCategory 및 errorType에 대한 값 관련 내용은 [Athena 오류 카탈로그](error-reference.md) 단원을 참조하세요. | 
| versionId | 세부 정보 객체 스키마의 버전 번호입니다. | 
| currentState | 이벤트 발생 시 쿼리가 다른 상태로 전환됩니다. | 
| previousState | 이벤트 발생 시 쿼리가 다른 상태에서 전환됩니다. | 
| statementType | 실행된 쿼리 문의 유형입니다. | 
| queryExecutionId | 실행된 쿼리에 대한 고유 식별자입니다. | 
| workgroupName | 쿼리가 실행된 작업 그룹의 이름입니다. | 
| sequenceNumber | 실행된 단일 쿼리와 관련된 수신 이벤트의 중복 제거 및 순서 지정을 수행할 수 있는 단순 증가 수치입니다. 동일한 상태 전환에 대해 중복 이벤트가 게시되면 sequenceNumber 값은 동일합니다. 드물지만 다시 대기열에 올리는 쿼리와 같이 쿼리에 상태 전환이 두 번 이상 발생하는 경우 sequenceNumber를 사용하여 동일한 currentState 및 previousState 값을 가진 이벤트의 순서를 지정할 수 있습니다. | 

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

다음 예제에서는 구독한 Amazon SNS 주제에 이벤트를 게시합니다. Athena가 쿼리되면 이메일을 받게 됩니다. 이 예제에서는 Amazon SNS 주제가 존재하고 사용자가 이를 구독했다고 가정합니다.

**Amazon SNS 주제에 Athena 이벤트를 게시하려면**

1. Amazon SNS 주제의 대상을 만듭니다. 다음 예제와 같이 Amazon SNS 주제에 게시할 수 있는 `events.amazonaws.com` 권한을 EventBridge 이벤트 서비스 보안 주체에 부여합니다.

   ```
   {
       "Effect":"Allow",
       "Principal":{
           "Service":"events.amazonaws.com"
       },
       "Action":"sns:Publish",
       "Resource":"arn:aws:sns:us-east-1:111111111111:your-sns-topic"
   }
   ```

1. 다음 예제와 같이 AWS CLI `events put-rule` 명령을 사용하여 Athena 이벤트에 대한 규칙을 만듭니다.

   ```
   aws events put-rule --name {ruleName} --event-pattern '{"source": ["aws.athena"]}'
   ```

1. 다음 예제와 같이 AWS CLI `events put-targets` 명령을 사용하여 Amazon SNS 주제 대상을 규칙에 연결합니다.

   ```
   aws events put-targets --rule {ruleName} --targets Id=1,Arn=arn:aws:sns:us-east-1:111111111111:your-sns-topic
   ```

1. Athena를 쿼리하고 호출되는 대상을 관찰합니다. Amazon SNS 주제에서 해당 이메일을 수신해야 합니다.

## Amazon Athena에서 AWS User Notifications 사용
<a name="monitoring-user-notifications"></a>

[AWS User Notifications](https://docs.aws.amazon.com/notifications/latest/userguide/what-is.html)을 사용하여 Amazon Athena 이벤트에 대한 알림을 받을 전송 채널을 설정할 수 있습니다. 이벤트가 지정한 규칙과 일치하면 알림을 받습니다. 이메일, [채팅 애플리케이션의 Amazon Q Developer](https://docs.aws.amazon.com/chatbot/latest/adminguide/what-is.html) 채팅 알림 또는 [AWS Console Mobile Application](https://docs.aws.amazon.com/consolemobileapp/latest/userguide/what-is-consolemobileapp.html) 푸시 알림을 비롯한 여러 채널을 통해 이벤트에 대한 알림을 받을 수 있습니다. [콘솔 알림 센터](https://console.aws.amazon.com/notifications/)에서도 알림을 볼 수 있습니다. User Notifications은 집계를 지원하므로 특정 이벤트 중에 받는 알림 수를 줄일 수 있습니다.

자세한 내용은 [https://docs.aws.amazon.com/notifications/latest/userguide/what-is.html](https://docs.aws.amazon.com/notifications/latest/userguide/what-is.html)를 참조하세요.

# 쿼리당 및 작업 그룹당 데이터 사용량 제어 구성
<a name="workgroups-setting-control-limits-cloudwatch"></a>

 Athena에서는 쿼리당 한도와 작업 그룹당 한도의 두 가지 비용 관리를 설정할 수 있습니다. 각 작업 그룹에 대해 쿼리당 한도 한 개와 작업 그룹당 한도 여러 개를 설정할 수 있습니다.
+ **쿼리당 제어 한도**는 쿼리당 스캔된 데이터의 총량을 지정합니다. 작업 그룹에서 실행하는 쿼리가 이 한도를 초과할 경우 쿼리가 취소됩니다. 한 작업 그룹에서 쿼리당 제어 한도를 한 개만 생성할 수 있으며 이 한도는 해당 작업 그룹에서 실행되는 각 쿼리에 적용됩니다. 이 한도를 변경해야 할 경우 수정할 수 있습니다. 자세한 방법은 [쿼리당 데이터 사용량 제어를 생성하려면](#configure-control-limit-per-query)을 참조하세요.
+ **작업 그룹 전역 데이터 사용량 제어 한도**는 이 작업 그룹에서 실행하는 모든 쿼리에 대해 지정된 시간 동안 스캔된 데이터의 총량을 지정합니다. 작업 그룹당 한도를 여러 개 만들 수 있습니다. 작업 그룹 전역 쿼리 한도를 사용하여 해당 작업 그룹에서 실행 중인 쿼리별로 스캔된 데이터의 시간별 또는 일간 집계에 대해 임계값을 여러 개 설정할 수 있습니다.

  스캔된 데이터의 집계량이 임계값을 초과할 경우 Amazon SNS 주제에 알림을 푸시할 수 있습니다. 이렇게 하려면 한도를 위반할 때 관리자에게 알리도록 Athena 콘솔에서 Amazon SNS 경보 및 작업을 구성합니다. 자세한 방법은 [작업 그룹당 데이터 사용량 제어를 생성하려면](#configure-control-limit-per-workgroup)을 참조하세요. CloudWatch 콘솔에서 Athena가 게시하는 모든 지표에 대해 경보 및 조치를 생성할 수도 있습니다. 예를 들어 실패한 쿼리의 수에 대한 경고를 설정할 수 있습니다. 이 경고는 쿼리 수가 특정 임계값에 이를 경우 관리자에게 이메일을 보내게 할 수 있습니다. 한도를 초과할 경우 조치는 지정된 사용자에게 Amazon SNS 경보 알림을 보냅니다.

  수행할 수 있는 기타 조치:
  + Lambda 함수를 간접적으로 호출합니다. 자세한 내용은 *Amazon Simple Notification Service 개발자 안내서*에서 [Amazon SNS 알림을 사용하여 Lambda 함수 호출](https://docs.aws.amazon.com/sns/latest/dg/sns-lambda-as-subscriber.html) 단원을 참조하세요.
  + 작업 그룹을 비활성화하여 쿼리가 더 이상 실행되지 않도록 합니다. 단계는 [작업 그룹 활성화 또는 비활성화](workgroups-enabled-disabled.md)를 참조하세요.

쿼리당 한도 및 작업 그룹당 한도는 서로 독립적입니다. 지정된 조치는 한도가 초과될 때마다 수행됩니다. 둘 이상의 사용자가 동일한 작업 그룹에서 동시에 쿼리를 실행할 경우, 각 쿼리는 지정된 한도를 초과하지 않지만, 스캔한 데이터의 총합은 작업 그룹당 데이터 사용 한도를 초과할 수 있습니다. 이 경우 Amazon SNS 경보가 사용자에게 전송됩니다.

## 쿼리당 데이터 사용량 제어 생성
<a name="create-a-per-query-data-usage-control"></a><a name="configure-control-limit-per-query"></a>

**쿼리당 데이터 사용량 제어를 생성하려면**

쿼리당 제어 한도는 쿼리당 스캔된 데이터의 총량을 지정합니다. 작업 그룹에서 실행하는 쿼리가 이 한도를 초과할 경우 쿼리가 취소됩니다. 취소된 쿼리는 [Amazon Athena 요금](https://aws.amazon.com/athena/pricing/)에 따라 요금이 청구됩니다.
**참고**  
취소되거나 실패한 쿼리의 경우 Athena가 Amazon S3에 일부 결과를 이미 썼을 수 있습니다. 이 경우 Athena는 결과가 저장된 Amazon S3 접두사에서 일부 결과를 삭제하지 않습니다. 일부 결과를 포함한 Amazon S3 접두사는 제거해야 합니다. Athena는 Amazon S3 멀티파트 업로드를 사용하여 Amazon S3에 데이터를 씁니다. 쿼리가 실패할 경우 멀티파트 업로드를 종료하도록 버킷 수명 주기 정책을 설정할 것을 권장합니다. 자세한 내용은 *Amazon Simple Storage Service 사용 설명서*의 [버킷 수명 주기 정책을 사용한 미완료 멀티파트 업로드 중단](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config)을 참조하세요.
특정 조건에서 Athena는 자동으로 쿼리 실행을 다시 시도할 수 있습니다. 대부분의 경우 이러한 쿼리는 성공적으로 완료되며 쿼리 ID는 `Completed`로 표시됩니다. 이러한 쿼리는 초기 시도 중 부분적인 결과를 기록했을 수 있으며 불완전한 멀티파트 업로드를 생성할 수 있습니다.

한 작업 그룹에서 쿼리당 제어 한도를 한 개만 생성할 수 있으며 이 한도는 해당 작업 그룹에서 실행되는 각 쿼리에 적용됩니다. 이 한도를 변경해야 할 경우 수정할 수 있습니다.

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 탐색 창에서 **작업 그룹**(Workgroups)을 선택합니다.

1. 목록에서 작업 그룹을 선택합니다.

1. **실행 제어** 탭에서 **제어 편집**을 선택하세요.

1. **데이터 스캔 제한** 값을 편집하세요.
   + 10MB(최소)\$17EB(최대) 범위의 값을 지정하세요.
   + 드롭다운 목록에서 단위 값(예: **킬로바이트 KB** 또는 **엑사바이트 EB**)을 선택하세요.
**참고**  
기본 작업은 쿼리가 제한을 초과할 경우 쿼리를 취소하는 것입니다. 이 설정은 변경할 수 없습니다.

1. **저장**을 선택하여 변경 사항을 적용하세요.

## 작업 그룹당 데이터 사용량 알림 생성 또는 편집
<a name="create-a-per-workgroup-data-usage-alert"></a><a name="configure-control-limit-per-workgroup"></a>

**작업 그룹당 데이터 사용량 알림 생성**

작업 그룹에서 실행되는 쿼리가 특정 기간 내에 지정된 양의 데이터를 스캔할 때 여러 경고 임계값을 설정할 수 있습니다. 알림은 Amazon CloudWatch 경보를 사용하여 구현되며 작업 그룹의 모든 쿼리에 적용됩니다. 임계값에 도달하면 Amazon SNS에서 지정한 사용자에게 이메일을 보내도록 할 수 있습니다. 임계값에 도달하면 쿼리가 자동으로 취소되지 않습니다.

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 콘솔 탐색 창이 표시되지 않으면 왼쪽의 확장 메뉴를 선택합니다.

1. 탐색 창에서 **작업 그룹**(Workgroups)을 선택합니다.

1. 목록에서 작업 그룹을 선택합니다.

1. **편집(Edit)**을 선택하여 작업 그룹의 설정을 편집합니다.

1. 아래로 스크롤하여 **작업 그룹 데이터 사용량 알림 - 선택 사항**을 확장합니다.

1. **알림 추가(Add a alert)**를 선택합니다.

1. **데이터 사용량 임계값 구성(Data usage threshold configuration)**에 대해 다음과 같이 값을 지정합니다.
   + **데이터 임계값(Data threshold)**에 숫자를 지정한 다음 드롭다운 목록에서 단위 값을 선택합니다.
   + **기간(Time period)** 드롭다운 목록에서 시간을 선택합니다.
   + **SNS 주제 선택(SNS topic selection)** 드롭다운 목록에서 Amazon SNS 주제를 선택합니다. 또는 **SNS 주제 생성(Create SNS topic)**을 선택하고 [Amazon SNS 콘솔](https://console.aws.amazon.com/sns/v2/home)로 바로 이동해 Amazon SNS 주제를 생성한 후 Athena 계정의 사용자 중 하나에 대해 이 주제의 구독을 설정합니다. 자세한 내용은 *Amazon Simple Notification Service 개발자 안내서*의 [Amazon SNS 시작하기](https://docs.aws.amazon.com/sns/latest/dg/sns-getting-started.html)를 참조하세요.

1. 새 알림을 생성하는 경우 **알림 추가(Add alert)**를 선택하고 기존 알림을 편집한 경우 **저장(Save)**을 선택합니다.

# Athena 작업 그룹 API 사용
<a name="workgroups-api-list"></a>

다음은 Athena 작업 그룹에 사용되는 몇 가지 REST API 작업입니다. `ListWorkGroups`를 제외한 다음 모든 작업에서 작업 그룹을 지정해야 합니다. `StartQueryExecution`과 같은 다른 작업에서는 작업 그룹 파라미터가 선택 사항이며 여기서 작업을 설명하지 않습니다. 전체 작업 목록은 [Amazon Athena API 참조](https://docs.aws.amazon.com/athena/latest/APIReference/)를 참조하세요.
+  [CreateWorkGroup](https://docs.aws.amazon.com/athena/latest/APIReference/API_CreateWorkGroup.html) 
+  [DeleteWorkGroup](https://docs.aws.amazon.com/athena/latest/APIReference/API_DeleteWorkGroup.html) 
+  [GetWorkGroup](https://docs.aws.amazon.com/athena/latest/APIReference/API_GetWorkGroup.html) 
+  [ListWorkGroups](https://docs.aws.amazon.com/athena/latest/APIReference/API_ListWorkGroups.html) 
+  [UpdateWorkGroup](https://docs.aws.amazon.com/athena/latest/APIReference/API_UpdateWorkGroup.html) 



# 작업 그룹 오류 문제 해결
<a name="workgroups-troubleshooting"></a>

다음 팁을 사용하여 작업 그룹의 문제를 해결하세요.
+ 계정의 개별 사용자에 대한 권한을 확인합니다. 사용자가 쿼리 결과의 위치 및 쿼리를 실행하려는 작업 그룹에 대해 액세스 권한이 있어야 합니다. 사용자가 작업 그룹을 전환할 경우 두 작업 그룹 모두에 대해 권한이 있어야 합니다. 자세한 내용은 [IAM 정책을 사용하여 작업 그룹 액세스 제어](workgroups-iam-policy.md) 섹션을 참조하세요.
+ Athena 콘솔의 컨텍스트에 주의를 기울여서 어느 작업 그룹에서 쿼리를 실행하려 하고 있는지 확인합니다. 드라이버를 사용할 경우 필요한 드라이버에 작업 그룹을 설정해야 합니다. 자세한 내용은 [쿼리용 작업 그룹 지정](specify-wkgroup-to-athena-in-which-to-run-queries.md) 섹션을 참조하세요.
+ API 또는 드라이버를 사용하여 쿼리를 실행할 경우 개별 쿼리에 대해서는 [OutputLocation](https://docs.aws.amazon.com/athena/latest/APIReference/API_ResultConfiguration.html#athena-Type-ResultConfiguration-OutputLocation)(클라이언트 측)을 사용하여 쿼리 결과 위치를 지정해야 합니다. 작업 그룹의 경우 [WorkGroupConfiguration](https://docs.aws.amazon.com/athena/latest/APIReference/API_WorkGroupConfiguration.html)을 사용합니다. 두 방법 중 하나를 사용하여 위치를 지정하지 않은 경우 쿼리 런타임 중에 Athena에서 오류가 발생합니다.
+ 클라이언트 측 설정을 작업 그룹 설정으로 재정의한 경우 쿼리 결과 위치에 대한 오류가 발생할 수 있습니다. 예를 들어 작업 그룹의 사용자가, 쿼리 결과를 저장하기 위한 Amazon S3의 작업 그룹 위치에 대해 권한이 없을 수 있습니다. 이 경우 필요한 권한을 추가하세요.
+ 작업 그룹은 API 작업의 동작에 변경을 적용합니다. 다음과 같은 기존 API 작업을 호출하려면 계정의 사용자들이 작업을 수행하는 작업 그룹에 대한 리소스 기반 권한을 IAM에서 소유해야 합니다. 기존의 작업 그룹 및 작업 그룹 작업에 대한 권한이 없을 경우 **CreateNamedQuery**, **DeleteNamedQuery**, **GetNamedQuery**, **ListNamedQueries**, **StartQueryExecution**, **StopQueryExecution**, **ListQueryExecutions**, **GetQueryExecution**, **GetQueryResults**, **GetQueryResultsStream**(이 API 작업은 드라이버와 함께 사용하는 경우에만 사용 가능하며 공개적으로 사용하는 경우에는 노출되지 않음) API 작업은 `AccessDeniedException`을 발생시킵니다. 자세한 내용은 *서비스 권한 부여 참조*에서 [Amazon Athena에 사용되는 작업, 리소스 및 조건 키](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonathena.html)를 참조하세요.

  **BatchGetQueryExecution** 및 **BatchGetNamedQuery** API 작업에 대한 호출은 사용자가 액세스 권한이 있는 작업 그룹에서 실행한 쿼리에 대해서만 정보를 반환합니다. 사용자가 작업 그룹에 대해 액세스 권한이 없을 경우 이러한 API 작업은 처리되지 않은 ID 목록에 승인되지 않은 쿼리 ID를 포함시켜 반환합니다. 자세한 내용은 [Athena 작업 그룹 API 사용](workgroups-api-list.md) 단원을 참조하세요.
+ 쿼리가 실행되는 작업 그룹이 [쿼리 결과 위치 강제 적용(enforced query results location)](workgroups-settings-override.md)으로 구성된 경우 CTAS 쿼리에 대해 `external_location`을 지정하면 안 됩니다. 이러한 경우 Athena에서 오류가 발생하고 `external_location`을 지정한 쿼리가 실패합니다. 예를 들어 쿼리 결과 위치에 대해 클라이언트 측 설정의 재정의할 경우 이 쿼리가 실패하고 작업 그룹에서 해당 위치 `CREATE TABLE <DB>.<TABLE1> WITH (format='Parquet', external_location='s3://amzn-s3-demo-bucket/test/') AS SELECT * FROM <DB>.<TABLE2> LIMIT 10;`를 사용합니다.

다음과 같은 오류가 나타날 수 있습니다. 다음 표에는 작업 그룹과 관련된 몇 가지 오류 목록과 권장 해결 방법이 나와 있습니다.


**작업 그룹 오류**  

| 오류 | 발생 조건... | 
| --- | --- | 
|  취소됨 쿼리 상태. 스캔한 바이트 제한을 초과했습니다. | 쿼리가 쿼리당 데이터 한도에 도달하여 취소되었습니다. 데이터를 읽는 양을 줄이도록 쿼리를 다시 작성하거나 계정 관리자에게 문의하세요. | 
|  arn:aws:iam::123456789012:user/abc 사용자는 arn:aws:athena:us-east-1:123456789012:workgroup/workgroupname 리소스에 대해 athena:StartQueryExecution 작업을 수행하도록 승인되지 않았습니다. | 사용자가 작업 그룹에서 쿼리를 실행했으나 작업 그룹에 대해 액세스 권한이 없습니다. 작업 그룹에 대해 액세스 권한을 갖도록 정책을 업데이트하세요. | 
|  INVALID\$1INPUT. <name> 작업 그룹이 비활성화되었습니다. | 사용자가 작업 그룹에서 쿼리를 실행했으나 작업 그룹이 비활성화되었습니다. 관리자가 작업 그룹을 비활성화했을 수 있습니다. 또한 해당 작업 그룹에 대해 액세스 권한이 없을 수 있습니다. 두 경우 모두 액세스 권한을 가진 관리자에게 연락하여 작업 그룹을 수정해 달라고 요청하세요. | 
|  INVALID\$1INPUT. <name> 작업 그룹을 찾을 수 없습니다. | 사용자가 작업 그룹에서 쿼리를 실행했으나 작업 그룹이 존재하지 않습니다. 작업 그룹이 삭제되었을 수 있습니다. 다른 작업 그룹으로 전환하여 쿼리를 실행하세요. | 
|  InvalidRequestException: StartQueryExecution 작업을 호출하는 동안 출력 위치를 제공하지 않았습니다. 출력 위치는 Workgroup 결과 구성 설정 또는 API 입력으로 필요합니다. |  사용자가 쿼리 결과 위치를 지정하지 않고 API를 사용하여 쿼리를 실행했습니다. 개별 쿼리에 대해 [OutputLocation](https://docs.aws.amazon.com/athena/latest/APIReference/API_ResultConfiguration.html#athena-Type-ResultConfiguration-OutputLocation)(클라이언트 측)을 사용하여 또는 작업 그룹에서 [WorkGroupConfiguration](https://docs.aws.amazon.com/athena/latest/APIReference/API_WorkGroupConfiguration.html)을 사용하여 쿼리 결과 위치를 설정해야 합니다.  | 
|   CTAS(Create Table As Select) 쿼리는 모든 쿼리에 대해 중앙 집중식 출력 위치를 적용하는 'external\$1location' 속성과 함께 Athena 작업 그룹에 제출되었기 때문에 실패했습니다. 'external\$1location' 속성을 제거하고 쿼리를 다시 제출하세요.  | 쿼리를 실행한 작업 그룹이 [쿼리 결과 위치 강제 적용](workgroups-settings-override.md)으로 구성된 경우 CTAS 쿼리에 대해 external\$1location을 지정하세요. 이 경우 external\$1location을 제거하고 쿼리를 다시 실행하세요. | 
| prepared\$1statement\$1name 준비된 문을 생성할 수 없습니다. 이 작업 그룹에서 준비된 문 수가 1000개 제한을 초과했습니다. | 이 작업 그룹에 1,000개 제한을 초과하는 준비된 문이 포함되어 있습니다. 이 문제를 해결하려면 [DEALLOCATE PREPARE](sql-deallocate-prepare.md)를 사용해 작업 그룹에서 준비된 문을 하나 이상 제거합니다. 또는 새 작업 그룹을 생성합니다. | 

# 쿼리 처리 용량 관리
<a name="capacity-management"></a>

용량 예약을 사용하여 Athena에서 실행하는 쿼리에 대한 전용 서버리스 처리 용량을 확보할 수 있습니다. 용량 예약을 통해 가장 중요한 워크로드의 우선순위를 지정하고 해당 워크로드를 제어 및 조정할 수 있는 워크로드 관리 기능을 이용할 수 있습니다. 예를 들어 용량을 추가하여 동시에 실행할 수 있는 쿼리 수를 늘리고 용량을 사용할 수 있는 워크로드를 제어하며 워크로드 사이에서 용량을 공유할 수 있습니다. 용량은 서버리스이고 Athena에서 완전하게 관리되며 필요한 시간 동안 보관됩니다. 설정이 쉽고 SQL 문을 변경할 필요가 없습니다.

쿼리의 처리 용량을 확보하려면 용량 예약을 생성하고 필요한 데이터 처리 장치(DPU) 수를 지정하며 예약에 하나 이상의 작업 그룹을 할당합니다.

용량 예약을 사용할 때 작업 그룹은 중요한 역할을 합니다. 작업 그룹을 사용하면 쿼리를 논리적 그룹이나 사용 사례로 구성할 수 있습니다. 용량 예약을 사용하면 작업 그룹에 용량을 선택적으로 할당하여 각 작업 그룹에 대한 쿼리의 작동 방식과 청구 방식을 제어할 수 있습니다. 작업 그룹에 대한 자세한 내용은 [작업 그룹을 사용하여 쿼리 액세스 및 비용 제어](workgroups-manage-queries-control-costs.md) 섹션을 참조하세요.

용량 예약에 작업 그룹을 할당하면 이러한 쿼리에 우선순위를 부여할 수 있습니다. 예약 용량에서 실행되고 DDL 및 DML 쿼리 할당량에 포함되지 않기 때문입니다. 예를 들어 시간이 중요한 금융 보고 쿼리에 사용되는 작업 그룹에 용량을 할당하여 해당 쿼리를 다른 작업 그룹의 덜 중요한 쿼리와 분리할 수 있습니다. 이렇게 하면 중요한 워크로드에서 예측 가능한 방식으로 쿼리를 실행하면서 다른 워크로드를 독립적으로 실행할 수 있습니다.

용량 예약과 작업 그룹을 함께 사용하여 다양한 요구 사항을 충족할 수 있습니다. 다음은 몇 가지 예제 시나리오입니다.
+ **중요한 쿼리 격리** - 중요한 워크로드가 필요할 시점에 필요한 용량을 확보하게 하기 위해 용량 예약을 생성하고 해당 작업 그룹을 예약에 할당합니다. 지정된 작업 그룹의 쿼리만 예약의 처리 용량을 사용합니다. 예를 들어 프로덕션 애플리케이션을 지원하는 쿼리를 신뢰할 수 있는 방식으로 실행하려면 해당 쿼리에 대한 프로덕션 작업 그룹을 용량 예약에 할당합니다. 쿼리를 개발할 때 예약에 연결되지 않은 별도의 작업 그룹을 사용하고 준비가 되면 쿼리를 프로덕션으로 이전합니다.
+ **유사한 워크로드에서 용량 공유** - 여러 워크로드가 하나의 예약에서 용량을 공유할 수 있습니다. 이를 통해 이러한 워크로드에 대해 예측 가능한 비용을 얻고 워크로드의 동시성을 제어할 수 있습니다. 예를 들어 지연된 쿼리 실행 시작 시간을 허용하는 예약된 워크로드가 있는 경우 단일 예약에 작업 그룹을 할당할 수 있습니다. 그러면 동일한 계정에서 실행되는 대화형 쿼리에 대한 DDL 및 DML 쿼리 할당량을 확보하여 지연 시간을 최소화하면서 이러한 쿼리가 시작됩니다.

## DPU 이해
<a name="capacity-management-understanding-dpus"></a>

용량은 데이터 처리 장치(DPU)로 측정됩니다. DPU는 Athena에서 사용자를 대신해 데이터에 액세스하고 데이터를 처리하는 데 사용하는 서버리스 컴퓨팅 및 메모리 리소스를 나타냅니다. 보통 1개의 DPU는 4개의 vCPU와 16GB의 메모리를 제공합니다. 보유하는 DPU 수는 동시에 실행할 수 있는 쿼리 수에 영향을 줍니다. 예를 들어 256개의 DPU를 포함하는 예약은 128개의 DPU를 포함하는 예약보다 약 두 배 더 많은 동시 쿼리 수를 지원할 수 있습니다.

용량 요구 사항 추정에 대한 자세한 내용은 [용량 요구 사항 결정](capacity-management-requirements.md) 섹션을 참조하세요. 요금 정보는 [Amazon Athena 요금](https://aws.amazon.com/athena/pricing/)을 참조하세요.

## 고려 사항 및 제한 사항
<a name="capacity-management-considerations-limitations"></a>
+ 동일한 계정에서 동시에 스캔한 데이터를 기반으로 용량 예약 및 쿼리별 청구를 사용할 수 있습니다.
+ 용량 예약에서 실행되는 쿼리는 DDL 및 DML 쿼리 할당량에 포함되지 않습니다.
+ 다른 쿼리를 처리하는 데 용량이 사용 중인 경우 새로 제출된 쿼리는 용량을 사용할 수 있을 때까지 대기열에 추가됩니다. 대기열에서 허용되는 최대 시간은 10시간입니다.
+ 작업 그룹은 한 번에 하나의 용량 예약에 할당할 수 있습니다. 단일 예약에 총 20개의 작업 그룹을 할당할 수 있습니다. 예약에 여러 작업 그룹을 할당하면 여러 작업 그룹에서 용량이 공유되고 제출 순서에 따라 쿼리에 할당됩니다. Athena가 쿼리에 용량을 동적으로 할당하는 방식 때문에 실행 순서는 달라질 수 있습니다.
+ Athena는 복잡성에 따라 DML 쿼리에 4\$1124개의 DPU를 자동으로 할당합니다. DDL 쿼리는 각각 4개의 DPU를 소비합니다. 자세한 내용은 다음 주제를 참조하세요.
  + [용량 요구 사항 결정](capacity-management-requirements.md)
  + [용량 사용량 제어](capacity-management-control-capacity-usage.md)
+ 각 용량 예약에 필요한 최소 DPU 수는 4개입니다. 요금 정보는 [Amazon Athena 요금](https://aws.amazon.com/athena/pricing/)을 참조하세요.
+ 계정 및 리전당 최대 1,000개의 DPU를 포함하는 최대 100개의 용량 예약을 생성할 수 있습니다. 사용 사례에 1,000개가 넘는 DPU가 필요한 경우 [athena-feedback@amazon.com](mailto:athena-feedback@amazon.com?subject=Athena Provisioned Capacity DPU Limit Request)으로 문의하세요.
+ 용량에 대한 요청은 보장되지 않으며, 완료하는 데 최대 30분이 소요될 수 있습니다. 용량은 다른 용량 예약(AWS 계정 또는 AWS 리전)으로 이전할 수 없습니다.
+ `DPUConsumed` CloudWatch 지표는 예약 단위가 아닌 작업 그룹 단위입니다. 따라서 작업 그룹을 한 예약에서 다른 예약으로 이동하면 해당 작업 그룹이 첫 번째 예약에 속했던 시점의 데이터가 `DPUConsumed` 지표에 포함됩니다. Athena에서 CloudWatch 지표를 사용하는 방법에 대한 자세한 내용은 [CloudWatch를 사용하여 Athena 쿼리 지표 모니터링](query-metrics-viewing.md) 섹션을 참조하세요.
+ 예약에 할당된 작업 그룹을 삭제하려면 먼저 예약에서 작업 그룹을 제거합니다.
+ Apache Spark를 사용하도록 구성된 작업 그룹은 지원되지 않습니다.
+ 다음 상용 AWS 리전에서는 용량 예약을 사용할 수 없습니다.
  + 이스라엘(텔아비브)
  + 중동(UAE)
  + 중동(바레인)
  + 아시아 태평양(뉴질랜드)

**Topics**
+ [DPU 이해](#capacity-management-understanding-dpus)
+ [고려 사항 및 제한 사항](#capacity-management-considerations-limitations)
+ [용량 요구 사항 결정](capacity-management-requirements.md)
+ [용량 예약 생성](capacity-management-creating-capacity-reservations.md)
+ [용량 사용량 제어](capacity-management-control-capacity-usage.md)
+ [자동으로 용량 조정](capacity-management-automatically-adjust-capacity.md)
+ [예약 관리](capacity-management-managing-reservations.md)
+ [용량 예약에 대한 IAM 정책](capacity-reservations-iam-policy.md)
+ [Athena 용량 예약 API](capacity-management-api-list.md)

# 용량 요구 사항 결정
<a name="capacity-management-requirements"></a>

용량 예약을 생성하기 전에 올바른 DPU 수를 할당할 수 있도록 필요한 용량을 추정할 수 있습니다. 또한 예약을 사용한 후에 예약에서 용량의 부족 또는 초과 상태를 확인하는 것이 좋습니다. 이 주제에서는 이러한 추정을 위해 사용할 수 있는 기법과 함께 사용량 및 비용을 평가하는 몇 가지 AWS 도구도 설명합니다.

**Topics**
+ [필요한 용량 추정](#capacity-management-requirements-estimating)
+ [더 많은 용량이 필요하다는 신호](#capacity-management-requirements-insufficient-capacity)
+ [유휴 용량 확인](#capacity-management-requirements-idle-capacity)
+ [DPU 소비 모니터링](#capacity-management-requirements-monitoring-dpu-consumption)

## 필요한 용량 추정
<a name="capacity-management-requirements-estimating"></a>

용량 요구 사항을 추정할 때 특정 쿼리에 필요한 용량과 일반적으로 필요한 용량이라는 두 가지 측면을 고려하는 것이 좋습니다.

### 쿼리당 용량 요구 사항 추정
<a name="capacity-management-requirements-estimating-query"></a>

쿼리에 필요할 수 있는 DPU 수를 결정하려는 경우 다음 지침을 사용할 수 있습니다.
+ DDL 쿼리는 4개의 DPU를 소비합니다.
+ DML 쿼리는 4\$1124개의 DPU를 소비합니다.

Athena는 쿼리가 제출될 때 DML 쿼리에 필요한 DPU 수를 결정합니다. 이 수는 데이터 크기, 스토리지 형식, 쿼리 구성 및 기타 요인에 따라 달라집니다. 일반적으로 Athena는 가장 적으면서 가장 효율적인 DPU 수를 선택하려고 합니다. Athena에서 쿼리를 성공적으로 완료하는 데 더 많은 컴퓨팅 성능이 필요하다고 판단하면 쿼리에 할당된 DPU 수가 늘어납니다.

### 워크로드별 용량 요구 사항 추정
<a name="capacity-management-requirements-estimating-workload"></a>

여러 쿼리를 동시에 실행하는 데 필요한 용량을 결정하려면 다음 테이블의 일반 지침을 고려합니다.


****  

| 동시 쿼리 수 | 필요한 DPU 수 | 
| --- | --- | 
| 10 | 40개 이상 | 
| 20 | 96개 이상 | 
| 30개 이상 | 240개 이상 | 

필요한 실제 DPU 수는 목표와 분석 패턴에 따라 달라집니다. 예를 들어 쿼리를 대기열에 넣지 않고 즉시 시작하려는 경우 최대 동시 쿼리 수요를 결정한 후 적절히 DPU 수를 프로비저닝합니다.

최대 수요보다 적게 DPU를 프로비저닝할 수 있지만, 최대 수요가 발생하면 대기열이 나타날 수 있습니다. 대기열이 나타나면 Athena는 쿼리를 대기열에 넣고 사용 가능한 용량이 확보되면 쿼리를 실행합니다.

고정된 예산 안에서 쿼리를 실행하는 것이 목표인 경우 [AWS 요금 계산기](https://calculator.aws/#/addService/Athena)를 사용하여 예산에 맞는 DPU 수를 결정할 수 있습니다.

마지막으로, 데이터 크기, 스토리지 형식, 쿼리 작성 방식이 쿼리에 필요한 DPU 수에 영향을 준다는 점을 기억하세요. 쿼리 성능을 높이려면 데이터를 압축 또는 파티셔닝하거나 열 형식으로 변환할 수 있습니다. 자세한 내용은 [Athena 성능 최적화](performance-tuning.md) 섹션을 참조하세요.

## 더 많은 용량이 필요하다는 신호
<a name="capacity-management-requirements-insufficient-capacity"></a>

할당한 용량이 부족함을 알리는 두 가지 징후로, 용량 부족 오류 메시지가 나타나거나 대기열에 쿼리가 들어갑니다.

용량 부족 오류 메시지와 함께 쿼리에 실패하는 경우 용량 예약의 DPU 수가 쿼리에 비해 너무 적습니다. 예를 들어 24개의 DPU로 예약한 상태에서 24개가 넘는 DPU가 필요한 쿼리를 실행하면 쿼리에 실패합니다. Athena의 [EventBridge 이벤트](athena-events.md)를 사용하여 이 쿼리 오류를 모니터링할 수 있습니다. DPU를 더 추가하고 쿼리를 다시 실행하세요.

대기열에 있는 쿼리가 많으면 다른 쿼리에서 용량을 완전히 사용하고 있다는 의미입니다. 대기열을 줄이려면 다음 중 하나를 수행합니다.
+ 예약에 DPU를 추가하여 쿼리 동시 처리 기능을 개선합니다.
+ 예약에서 작업 그룹을 제거하여 다른 쿼리에 사용할 용량을 확보합니다.

대기열에 있는 쿼리가 너무 많은지 확인하려면 용량 예약에서 작업 그룹에 대한 Athena 쿼리 대기열 시간 [CloudWatch 지표](query-metrics-viewing.md)를 사용합니다. 값이 원하는 임계값을 초과하는 경우 용량 예약에 DPU를 추가할 수 있습니다.

## 유휴 용량 확인
<a name="capacity-management-requirements-idle-capacity"></a>

유휴 용량을 확인하려면 예약의 DPU 수를 줄이거나 워크로드를 늘린 후에 결과를 관찰할 수 있습니다.

**유휴 용량을 확인하려면**

1. 다음 중 하나를 수행하세요.
   + 예약의 DPU 수 감소(사용 가능한 리소스 감소)
   + 예약에 작업 그룹 추가(워크로드 증가)

1. [CloudWatch](query-metrics-viewing.md)를 사용하여 쿼리 대기열 시간을 측정합니다.

1. 대기열 시간이 원하는 수준을 초과하면 다음 중 하나를 수행합니다.
   + 작업 그룹 제거
   + 용량 예약에 DPU 추가

1. 변경할 때마다 성능과 쿼리 대기열 시간을 확인합니다.

1. 워크로드 및/또는 DPU 수를 계속 조정하여 원하는 균형을 맞춥니다.

원하는 기간이 아닐 때 용량을 유지하지 않으려면 예약을 [취소](capacity-management-cancelling-a-capacity-reservation.md)하고 나중에 다른 예약을 생성할 수 있습니다. 그러나 최근에 다른 예약에서 용량을 취소했어도 새 요량에 대한 요청은 보장되지 않으며, 새 예약을 생성하는 데 시간이 걸립니다.

## DPU 소비 모니터링
<a name="capacity-management-requirements-monitoring-dpu-consumption"></a>

쿼리가 실행된 후 쿼리에서 소비하는 DPU를 보고 용량 추정치를 세부 조정할 수 있습니다. Athena는 콘솔, API 작업 및 CloudWatch를 통해 DPU 소비 지표를 제공합니다. 이 정보는 예상보다 더 많거나 적은 리소스를 소비하는 쿼리를 식별하고 실제 데이터를 기반으로 용량 할당을 최적화하는 데 도움이 됩니다. DPU 소비 보기 및 추적에 대한 자세한 내용은 [DPU 사용량 모니터링](capacity-management-control-capacity-usage.md#capacity-management-monitor-dpu-usage) 섹션을 참조하세요.

## 용량 요구 사항 및 비용을 평가하기 위한 도구
<a name="capacity-management-requirements-tools"></a>

AWS에서 다음 서비스 및 기능을 사용하여 Athena 사용량 및 비용을 측정할 수 있습니다.

### CloudWatch 지표
<a name="capacity-management-requirements-tools-cloudwatch-metrics"></a>

쿼리 관련 지표를 작업 그룹 수준에서 Amazon CloudWatch에 게시하도록 Athena를 구성할 수 있습니다. 작업 그룹에 대한 지표를 활성화하면 작업 그룹 쿼리에 대한 지표가 Athena 콘솔의 작업 그룹 세부 정보 페이지에 표시됩니다.

CloudWatch에 게시된 Athena 지표와 해당 수치에 대한 자세한 내용은 [CloudWatch를 사용하여 Athena 쿼리 지표 모니터링](query-metrics-viewing.md) 섹션을 참조하세요.

### CloudWatch 사용량 지표
<a name="capacity-management-requirements-tools-cloudwatch-usage-metrics"></a>

CloudWatch 사용량 지표를 사용하여 CloudWatch 그래프 및 대시보드에서 현재 서비스 사용량을 표시하여 계정에서 리소스가 어떻게 사용되고 있는지 확인할 수 있습니다. Athena의 경우 사용량 가용성 지표는 Athena에 대한 AWS [서비스 할당량](service-limits.md)에 해당합니다. 사용량이 서비스 할당량에 가까워지면 경고하는 경보를 구성할 수 있습니다.

자세한 내용은 [CloudWatch를 사용하여 Athena 사용량 지표 모니터링](monitoring-athena-usage-metrics.md) 섹션을 참조하세요.

### Amazon EventBridge 이벤트
<a name="capacity-management-requirements-tools-eventbridge-events"></a>

Amazon EventBridge와 함께 Amazon Athena를 사용하여 쿼리 상태에 대한 실시간 알림을 받을 수 있습니다. 사용자가 제출한 쿼리의 상태가 변경되면 Athena는 해당 쿼리 상태 전환에 대한 정보를 포함하는 이벤트를 EventBridge에 게시합니다. 원하는 이벤트에 대한 간단한 규칙을 작성하고 규칙과 일치하는 이벤트 발생 시 자동으로 작업을 수행하도록 할 수 있습니다.

자세한 정보는 다음 리소스를 참조하세요.
+ [EventBridge를 사용하여 Athena 쿼리 이벤트 모니터링](athena-events.md)
+ [Amazon EventBridge란 무엇인가요?](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html)
+ [Amazon EventBridge 이벤트](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-events.html) 

### Tags
<a name="capacity-management-requirements-tools-tags"></a>

Athena에서 용량 예약은 태그를 지원합니다. 태그는 키와 값으로 구성됩니다. Athena에서 비용을 추적하기 위해 AWS에서 생성된 비용 할당 태그를 사용할 수 있습니다. AWS에서는 비용 할당 태그를 사용하여 [Cost and Usage Report](https://docs.aws.amazon.com/cur/latest/userguide/what-is-cur.html)에서 리소스 비용을 구성합니다. 이 방법을 통해 AWS 비용을 더 쉽게 분류하고 추적할 수 있습니다. Athena에 대한 비용 할당 태그를 활성화하려면 [AWS 결제 및 비용 관리 콘솔](https://console.aws.amazon.com/billing/)을 사용합니다.

자세한 정보는 다음 리소스를 참조하세요.
+ [Athena 리소스 태깅](tags.md)
+ [AWS에서 생성하는 비용 할당 태그 활성화](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/activate-built-in-tags.html)
+ [AWS 비용 할당 태그 사용](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-alloc-tags.html)

# 용량 예약 생성
<a name="capacity-management-creating-capacity-reservations"></a>

먼저 필요한 수의 DPU가 포함된 용량 예약을 생성하고 해당 용량을 쿼리에 사용할 하나 이상의 작업 그룹을 할당합니다. 나중에 필요에 따라 용량을 조정하여 보다 일관된 성능을 제공하거나 비용을 효과적으로 관리할 수 있습니다. 용량 요구 사항 추정에 대한 자세한 내용은 [용량 요구 사항 결정](capacity-management-requirements.md) 섹션을 참조하세요.

**중요**  
용량에 대한 요청은 보장되지 않으며, 완료하는 데 최대 30분이 소요될 수 있습니다.

**용량 예약을 생성하려면**

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 콘솔 탐색 창이 표시되지 않으면 왼쪽의 확장 메뉴를 선택합니다.

1. **관리**, **용량 예약**을 선택합니다.

1. **용량 예약 생성**을 선택합니다.

1. **용량 예약 생성** 페이지에서 **용량 예약 이름**에 이름을 입력합니다. 이름은 1\$1128자로 고유해야 하며 a\$1z, A\$1Z, 0\$19, \$1(밑줄), .(마침표), -(하이픈)만 사용해야 합니다. 예약을 생성한 후에는 이름을 변경할 수 없습니다.

1. **DPU**의 경우 원하는 데이터 처리 장치(DPU)의 수를 선택하거나 입력합니다(증분 단위: 4). 자세한 내용은 [DPU 이해](capacity-management.md#capacity-management-understanding-dpus) 섹션을 참조하세요.

1. (선택 사항) **태그** 옵션을 확장하고 **새 태그 추가**를 선택하여 용량 예약 리소스에 연결할 사용자 지정 키 및 값 페어를 하나 이상 추가합니다. 자세한 내용은 [Athena 리소스 태깅](tags.md) 섹션을 참조하세요.

1. **검토**를 선택합니다.

1. **용량 예약 생성 확인** 프롬프트에서 DPU 수, AWS 리전 및 기타 정보를 확인합니다. 수락하는 경우 **제출**을 선택합니다.

   세부 정보 페이지에서 용량 예약 **상태**는 **대기 중**으로 표시됩니다. 예약 용량에서 쿼리를 실행할 수 있으면 상태가 **활성**으로 표시됩니다.

이제 예약에 하나 이상의 작업 그룹을 추가할 수 있습니다. 단계는 [예약에 작업 그룹 추가](capacity-management-adding-workgroups-to-a-reservation.md)를 참조하세요.

# 용량 사용량 제어
<a name="capacity-management-control-capacity-usage"></a>

최대 또는 최소 DPU 수에 대한 제어를 설정하여 Athena가 쿼리에 할당하는 DPU 수를 제어할 수 있습니다. 모든 쿼리에 대한 기준 제어를 설정하도록 작업 그룹 수준에서 이를 구성하거나 세분화된 제어를 위해 개별 쿼리 수준에서 구성할 수 있습니다. 그러면 쿼리 성능, 워크로드 동시성 및 비용을 직접 제어할 수 있습니다.
+ 최대 DPU 수를 설정하면 쿼리는 사용자가 지정한 것보다 더 많은 용량을 소비하지 못합니다. 따라서 비용 및 워크로드 동시성 제어가 간단해집니다. 예를 들어 용량 예약에 200개의 DPU가 있는 경우 쿼리당 최대 DPU 수를 8로 설정하면 25개의 쿼리를 동시에 실행할 수 있습니다. 예약을 400개의 DPU로 늘리면 50개의 쿼리를 동시에 실행할 수 있습니다.
+ 최소 DPU 수를 설정하면 원하는 최소 DPU 수로 쿼리가 실행되도록 보장합니다. 이는 쿼리에 대한 일반적인 용량 사용 프로파일을 미리 알고 있는 경우에 유용합니다.

**참고**  
DPU 사용 제어는 용량 예약으로 실행된 쿼리에만 적용됩니다.

**참고**  
모든 쿼리에 대해 동일한 수의 DPU를 사용하려면 최소 및 최대 DPU 수에 동일한 값을 사용합니다.

## 작업 그룹 수준에서 DPU 제어 설정
<a name="capacity-management-set-dpu-controls-workgroup-level"></a>

선택한 작업 그룹에 대한 워크로드 성능을 제어하고 비용을 관리하려면 작업 그룹 수준에서 DPU 제어를 설정합니다. 작업 그룹 수준에서 설정된 DPU 제어는 **클라이언트 측 설정 재정의**가 활성화된 경우 모든 쿼리에 적용됩니다.

**콘솔을 사용하여 DPU 제어를 설정하는 방법**

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 탐색 창에서 **작업 그룹(Workgroups)**을 선택합니다.

1. 용량 예약을 사용하는 작업 그룹을 선택하세요.

1. **실행 제어** 탭에서 **제어 편집**을 선택하세요.

1. 다음을 구성합니다.
   + **쿼리당 최소 DPU 수**에 4\$1124 사이의 값(증분 단위: 4)을 입력하세요.
   + **쿼리당 최대 DPU 수**에 4\$1124 사이의 값(증분 단위: 4)을 입력하세요.

1. **저장**을 선택합니다.

1. (선택 사항) **클라이언트 측 설정 재정의**를 선택하여 이러한 설정을 적용하고 쿼리 수준 DPU 구성을 무시하세요.

**AWS CLI를 사용하여 DPU 제어를 설정하는 방법**
+ `update-work-group` 명령을 사용하여 작업 그룹에 대한 DPU 제어를 설정합니다.

  ```
  aws athena update-work-group \
    --work-group my_workgroup \
    --configuration-updates '{
          "EngineConfiguration": {
              "Classifications": [
                  {
                      "Name": "athena-query-engine-properties",
                      "Properties": {
                          "max-dpu-count" : "24",
                          "min-dpu-count" : "12"
                          }
                      }
                  ]
          }}'
  ```

  `EnforceWorkGroupConfiguration`을 `true`로 설정하면 [StartQueryExecution](https://docs.aws.amazon.com/athena/latest/APIReference/API_StartQueryExecution.html)을 통해 제출할 때 작업 그룹 설정이 쿼리 수준에서 지정된 모든 DPU 제어를 재정의합니다. 이를 통해 작업 그룹의 모든 쿼리에서 일관된 리소스 할당이 보장됩니다.

## 개별 쿼리를 사용하여 DPU 제어 설정
<a name="capacity-management-set-dpu-controls-individual-queries"></a>

리소스 요구 사항이 서로 다른 쿼리에서 세분화된 제어가 필요한 경우 쿼리 수준 DPU 제어를 설정합니다. 쿼리 수준 DPU 제어는 작업 그룹에 **클라이언트 측 설정 재정의**가 활성화되어 있지 않은 한 작업 그룹 수준 설정보다 우선합니다.

**콘솔을 사용하여 쿼리에 대한 DPU 제어를 설정하는 방법**

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 탐색 창에서 **쿼리 편집기**를 선택합니다.

1. 용량 예약을 사용하는 작업 그룹을 선택하세요.

1. **쿼리 설정** 탭을 선택하세요.

1. **실행 제어** 섹션에서 **제어 편집**을 선택하세요.

1. 다음을 구성합니다.
   + **쿼리당 최소 DPU 수**에 4\$1124 사이의 값(증분 단위: 4)을 입력하세요.
   + **쿼리당 최대 DPU 수**에 4\$1124 사이의 값(증분 단위: 4)을 입력하세요.

1. **저장**을 선택합니다.

**AWS CLI를 사용하여 쿼리에 대한 DPU 제어를 설정하는 방법**
+ `engine-configuration` 파라미터와 함께 `start-query-execution` 명령을 사용하세요.

  ```
  aws athena start-query-execution \
    --query-string "SELECT * FROM my_table LIMIT 10" \
    --work-group "my_workgroup" \
    --engine-configuration '{
      "Classifications": [ {
          "Name": "athena-query-engine-properties",
              "Properties": {
                  "max-dpu-count" : "32",
                  "min-dpu-count" : "8"
                  }
              }
          ]}'
  ```

쿼리 수준 및 작업 그룹 수준 DPU 설정 간 관계는 다음과 같이 작업 그룹 구성에 따라 다릅니다.
+ **클라이언트 측 설정 재정의**가 활성화되면 모든 쿼리 수준 설정보다 작업 그룹 수준 DPU 제어가 우선합니다. 이를 통해 지정된 작업 그룹의 모든 쿼리에 대해 일관된 리소스 사용이 보장됩니다.
+ **클라이언트 측 설정 재정의**가 활성화되지 않은 경우 쿼리 수준 DPU 제어가 작업 그룹 수준 설정보다 우선합니다. 이를 통해 개별 쿼리를 유연하게 최적화할 수 있습니다.

어느 수준에서든 DPU 제어를 지정하지 않으면 Athena는 쿼리 복잡성에 따라 용량을 자동으로 할당합니다.

**참고**  
DDL 쿼리의 경우 최소 DPU 수의 최댓값은 4입니다. DDL 쿼리의 최솟값을 높게 설정하면 오류가 발생합니다.

## DPU 사용량 모니터링
<a name="capacity-management-monitor-dpu-usage"></a>

쿼리가 완료되면 DPU 사용량을 볼 수 있습니다. Athena는 콘솔, API 작업 및 CloudWatch를 통해 DPU 사용 지표를 제공합니다.

**콘솔에서 DPU 소비를 보는 방법**

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 탐색 창에서 **쿼리 편집기**를 선택합니다.

1. 쿼리가 완료되면 쿼리 결과 컨테이너에서 **소비된 DPU 수** 값을 확인하세요.

1. 과거 쿼리에 대한 DPU 소비를 보는 방법:

   1. 탐색 창에서 **최근 쿼리**를 선택하세요.

   1. 아직 표시되지 않은 경우 설정 아이콘을 선택하여 **소비된 DPU 수** 열을 테이블에 추가하세요.

   1. 완료된 각 쿼리에 대한 DPU 소비를 검토하세요.

1. 선택적으로 **쿼리 편집기**에서 **쿼리 통계** 탭을 선택하고 **소비된 DPU 수**를 검토하세요.

**API를 사용하여 DPU 소비를 검색하는 방법**

1. 다음 API 작업을 사용하여 프로그래밍 방식으로 DPU 소비를 검색하세요.
   + `GetQueryExecution` - 특정 쿼리에 대한 실행 세부 정보 반환
   + `BatchGetQueryExecution` - 여러 쿼리에 대한 실행 세부 정보 반환

1. AWS CLI 사용 예시:

   ```
   aws athena get-query-execution \
     --query-execution-id "123e4567-e89b-12d3-a456-426614174000"
   ```

   응답에서 `Statistics` 객체에 `DpuCount` 필드가 포함됩니다.

   ```
   {
     "QueryExecution": {
       "Statistics": {
         "DpuCount": 8
       }
     }
   }
   ```

**CloudWatch를 사용하여 DPU 사용량을 모니터링하는 방법**
+ Athena는 용량 사용률 및 기타 성능 데이터를 모니터링하는 데 도움이 되는 쿼리 관련 지표를 CloudWatch에 게시합니다. 자세한 내용은 [CloudWatch를 사용하여 Athena 쿼리 지표 모니터링](query-metrics-viewing.md)를 참조하세요.

# 자동으로 용량 조정
<a name="capacity-management-automatically-adjust-capacity"></a>

Athena의 오토 스케일링 솔루션을 사용하여 워크로드 사용률에 따라 예약 용량을 자동으로 조정할 수 있습니다. 사용률이 구성된 임계치를 초과하면 자동으로 용량을 추가하고 사용률이 낮은 기간에는 용량을 제거하여 비용을 절감합니다. 다양한 사용률 임계치, 최소 및 최대 DPU 수량, 조정 증분 및 사용률 평가 빈도를 설정하여 해당 동작을 사용자 지정할 수 있습니다. 이렇게 하면 수동 용량 조정을 없애면서 성능 요구 사항과 비용 최적화의 균형을 맞출 수 있습니다.

CloudFormation 템플릿을 사용하여 이 서버리스 솔루션을 배포합니다. 사용률 지표를 모니터링하고 조정 결정을 내리는 Step Functions 상태 머신을 생성합니다. 특정 요구 사항에 맞게 템플릿 또는 상태 머신을 추가로 사용자 지정할 수 있습니다.

시작하려면 Athena 콘솔을 사용하고 용량 예약 세부 정보 페이지에서 **오토 스케일링 설정**을 선택합니다. 그러면 템플릿이 미리 로드된 상태로 CloudFormation에 리디렉션됩니다. 또는 아래 절차를 따릅니다.

## 사전 조건
<a name="capacity-management-auto-scaling-prerequisites"></a>
+ 활성 용량 예약이 필요함
+ CloudFormation 스택 배포 및 Step Functions 리소스 생성에 필요한 IAM 권한

## CloudFormation 스택 시작
<a name="capacity-management-auto-scaling-launch-stack"></a>

자동화된 이 CloudFormation 템플릿은 Athena 용량 예약 오토 스케일링 솔루션을 배포합니다. 스택을 시작하기 전에 [사전 조건](#capacity-management-auto-scaling-prerequisites)에서 해당 단계를 완료해야 합니다.

[https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?&templateURL=https:%2F%2Fathena-downloads.s3.us-east-1.amazonaws.com%2F%2Ftemplates%2F%2Fcapacity-reservation-scaling%2F%2Fstate-machine%2F%2Fathena-capacity-reservation-scaling-template-v1.1.yaml](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?&templateURL=https:%2F%2Fathena-downloads.s3.us-east-1.amazonaws.com%2F%2Ftemplates%2F%2Fcapacity-reservation-scaling%2F%2Fstate-machine%2F%2Fathena-capacity-reservation-scaling-template-v1.1.yaml) 

**오토 스케일링 솔루션을 시작하는 방법**

1. [AWS Management Console](https://console.aws.amazon.com/)에 로그인하고 `AWSAccelerator-InstallerStack` CloudFormation 템플릿을 시작하도록 버튼을 선택하세요.

1. 이 템플릿은 기본적으로 미국 동부(버지니아 북부) 리전에서 시작됩니다. 다른 AWS 리전에서 솔루션을 시작하려면 콘솔 탐색 표시줄에서 리전 선택기를 사용하세요.

1. **스택 생성** 페이지에서 **Amazon S3 URL** 텍스트 상자에 템플릿 URL이 있는지 확인하고 **다음**을 선택하세요.

1. **스택 세부 정보 지정** 페이지에서 솔루션 스택 이름을 할당합니다.

1. **파라미터**에서 이 솔루션 템플릿의 파라미터를 검토하고 필요에 따라 수정합니다. 이 솔루션은 다음과 같은 기본값을 사용합니다.  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/athena/latest/ug/capacity-management-automatically-adjust-capacity.html)
**참고**  
Athena의 용량 예약 요구 사항을 준수하려면 모든 DPU 값은 4의 배수여야 합니다.

1. **다음**을 선택합니다.

1. **스택 옵션 구성** 페이지에서 **다음**을 선택합니다.

1. **검토 및 생성** 페이지에서 설정을 검토하고 확인합니다. 템플릿이 IAM 리소스를 생성할 수 있음을 확인하는 확인란을 선택하세요.

1. **제출**을 선택하여 스택을 배포합니다.

   CloudFormation 콘솔의 **상태** 열에서 스택의 상태를 볼 수 있습니다. 몇 분 후에 `CREATE_COMPLETE` 상태를 수신합니다.

# 예약 관리
<a name="capacity-management-managing-reservations"></a>

**용량 예약** 페이지에서 용량 예약을 보고 관리할 수 있습니다. DPU 추가 또는 감소, 작업 그룹 할당 수정, 예약 태그 지정 또는 예약 취소와 같은 관리 작업을 수행할 수 있습니다.

**용량 예약을 보고 관리하려면**

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 콘솔 탐색 창이 표시되지 않으면 왼쪽의 확장 메뉴를 선택합니다.

1. **관리**, **용량 예약**을 선택합니다.

1. 용량 예약 페이지에서 다음 작업을 수행할 수 있습니다.
   + 용량 예약을 생성하려면 **용량 예약 생성**을 선택합니다.
   + 검색 상자를 사용하여 DPU의 이름 또는 수를 기준으로 예약을 필터링합니다.
   + 상태 드롭다운 메뉴를 선택하여 용량 예약 상태(예: **활성** 또는 **취소됨**)에 따라 필터링합니다. 예약 상태에 대한 자세한 내용은 [예약 상태 이해](#capacity-management-understanding-reservation-status) 섹션을 참조하세요.
   + 용량 예약에 대한 세부 정보를 보려면 예약에 대한 링크를 선택합니다. 예약 세부 정보 페이지에는 [용량 편집](capacity-management-editing-capacity-reservations.md), [작업 그룹 추가](capacity-management-adding-workgroups-to-a-reservation.md), [작업 그룹 제거](capacity-management-removing-a-workgroup-from-a-reservation.md), 예약 [취소](capacity-management-cancelling-a-capacity-reservation.md) 옵션이 포함되어 있습니다.
   + 예약을 편집하려면(예: DPU 추가 또는 제거) 예약에 대한 버튼을 선택하고 **편집**을 선택합니다.
   + 예약을 취소하려면 예약에 대한 버튼을 선택하고 **취소**를 선택합니다.

## 예약 상태 이해
<a name="capacity-management-understanding-reservation-status"></a>

다음 테이블에서는 용량 예약의 가능한 상태 값을 설명합니다.


****  

| Status | 설명 | 
| --- | --- | 
| 보류중 | Athena에서 용량 요청을 처리 중입니다. 쿼리를 실행할 용량이 준비되지 않았습니다. | 
| 활성 | 쿼리를 실행할 용량이 사용 가능합니다. | 
| 실패 | 용량에 대한 요청이 완료되지 않았습니다. 용량 요청 이행은 보장되지 않습니다. 실패한 예약 수는 계정의 DPU 한도 계산에 포함됩니다. 사용량을 확보하려면 예약을 취소해야 합니다. | 
| 업데이트 대기 중 | Athena에서 예약 변경을 처리 중입니다. 예를 들어 예약을 편집하여 DPU를 추가하거나 제거한 후에 이 상태가 나타납니다. | 
| 취소 중 | Athena에서 예약 취소 요청을 처리 중입니다. 예약을 사용하던 작업 그룹에서 여전히 실행 중인 쿼리는 완료할 수 있지만 작업 그룹의 다른 쿼리는 온디맨드 용량(프로비저닝되지 않음)을 사용합니다. | 
| 취소됨 |  용량 예약 취소가 완료됩니다. 취소된 예약은 콘솔에 45일 동안 남아 있습니다. 45일이 지나면 Athena에서 예약을 삭제합니다. 45일 동안 예약의 용도를 변경하거나 재사용할 수 없지만, 기록 참조를 위해 해당 태그를 참조하고 세부 정보를 볼 수 있습니다. 취소된 용량은 향후 재예약이 보장되지 않습니다. 또는 다른 예약(AWS 계정 또는 AWS 리전)으로 이전될 수 없습니다.  | 

## 활성 DPU 및 대상 DPU 이해
<a name="capacity-management-understanding-dpu-status"></a>

Athena 콘솔의 용량 예약 목록에서 예약에는 **활성 DPU** 및 **대상 DPU**라는 두 개의 DPU 값이 표시됩니다.
+ **활성 DPU** - 예약에서 쿼리를 실행하는 데 사용할 수 있는 DPU 수입니다. 예를 들어 100개의 DPU를 요청하고 해당 요청이 이행되면 **활성 DPU**는 **100**으로 표시됩니다.
+ **대상 DPU** - 예약에서 이동 처리 중인 DPU의 수입니다. 예약이 생성되거나 DPU 수의 증가 또는 감소가 대기 중인 경우 **대상 DPU**에는 **활성 DPU**와 다른 값이 표시됩니다.

예를 들어 DPU가 24개인 예약을 생성하는 요청을 제출하면 예약 **상태**는 **대기 중**, **활성 DPU**는 **0**, **대상 DPU**는 **24**로 표시됩니다.

DPU가 100개인 예약에서 예약을 편집하여 DPU를 20개로 늘리도록 요청하는 경우 **상태**는 **업데이트 대기 중**, **활성 DPU**는 **100**, **대상 DPU**는 **120**으로 표시됩니다.

DPU가 100개인 예약에서 예약을 편집하여 DPU를 20개로 줄이도록 요청하는 경우 **상태**는 **업데이트 대기 중**, **활성 DPU**는 **100**, **대상 DPU**는 **80**으로 표시됩니다.

이러한 전환 중에 Athena는 사용자 요청에 따라 DPU 수를 확보하거나 줄이기 위해 적극적으로 노력합니다. **활성 DPU**가 **대상 DPU**와 같아지면 대상 수에 도달한 것이며 대기 중인 변경 사항은 없습니다.

이러한 값을 프로그래밍 방식으로 검색하기 위해 [GetCapacityReserve](https://docs.aws.amazon.com/athena/latest/APIReference/API_GetCapacityReservation.html) API 작업을 호출할 수 있습니다. API는 **활성 DPU**와 **대상 DPU**를 `AllocatedDpus` 및 `TargetDpus`로 참조합니다.

**Topics**
+ [예약 상태 이해](#capacity-management-understanding-reservation-status)
+ [활성 DPU 및 대상 DPU 이해](#capacity-management-understanding-dpu-status)
+ [용량 예약 편집](capacity-management-editing-capacity-reservations.md)
+ [예약에 작업 그룹 추가](capacity-management-adding-workgroups-to-a-reservation.md)
+ [예약에서 작업 그룹 제거](capacity-management-removing-a-workgroup-from-a-reservation.md)
+ [용량 예약 취소](capacity-management-cancelling-a-capacity-reservation.md)
+ [용량 예약 삭제](capacity-management-deleting-a-capacity-reservation.md)

# 용량 예약 편집
<a name="capacity-management-editing-capacity-reservations"></a>

용량 예약을 생성한 후 DPU 수를 조정하고 사용자 지정 태그를 추가하거나 제거할 수 있습니다.

**용량 예약을 편집하려면**

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 콘솔 탐색 창이 표시되지 않으면 왼쪽의 확장 메뉴를 선택합니다.

1. **관리**, **용량 예약**을 선택합니다.

1. 용량 예약 목록에서 다음 중 하나를 수행합니다.
   + 예약 옆에 있는 버튼을 선택하고 **편집**을 선택합니다.
   + 예약 링크를 선택하고 **편집**을 선택합니다.

1. **DPU**의 경우 원하는 데이터 처리 장치의 수를 선택하거나 입력하세요. 자세한 내용은 [DPU 이해](capacity-management.md#capacity-management-understanding-dpus) 섹션을 참조하세요.
**참고**  
언제든지 활성 용량 예약에 DPU 추가를 요청할 수 있습니다.
예약이 활성화되고 1분이 경과했거나 DPU가 마지막으로 추가된 시점부터 활성 용량 예약에서 DPU 감소를 요청할 수 있습니다.
DPU 감소를 요청하면 Athena는 활성 DPU보다 유휴 DPU를 우선적으로 제거합니다. 쿼리에서 제거 대상으로 표시된 DPU를 사용하고 있는 경우 Athena는 쿼리가 완료될 때까지 기다린 후 DPU를 제거합니다.

1. (선택 사항) **태그**에서 **제거**를 선택하여 태그를 제거하거나 **새 태그 추가**를 선택하여 새 태그를 추가합니다.

1. **제출**을 선택합니다. 예약의 세부 정보 페이지에 업데이트된 구성이 표시됩니다.

# 예약에 작업 그룹 추가
<a name="capacity-management-adding-workgroups-to-a-reservation"></a>

용량 예약을 생성한 후 예약에 최대 20개의 작업 그룹을 추가할 수 있습니다. 예약에 작업 그룹을 추가하면 예약 용량으로 실행해야 하는 쿼리를 Athena에 알립니다. 예약에 연결되지 않은 작업 그룹의 쿼리는 스캔한 테라바이트(TB)당 기본 요금 모델을 사용하여 계속 실행됩니다.

예약에 작업 그룹이 두 개 이상 있는 경우 해당 작업 그룹의 쿼리는 예약 용량을 사용할 수 있습니다. 언제든지 작업 그룹을 추가하고 제거할 수 있습니다. 작업 그룹을 추가하거나 제거할 때 실행 중인 쿼리는 중단되지 않습니다.

예약이 대기 중 상태인 경우 추가한 작업 그룹의 쿼리는 예약이 활성화될 때까지 스캔한 테라바이트(TB)당 기본 요금 모델을 사용하여 계속 실행됩니다.

**용량 예약에 하나 이상의 작업 그룹을 추가하려면**

1. 용량 예약의 세부 정보 페이지에서 **작업 그룹 추가**를 선택합니다.

1. **작업 그룹 추가** 페이지에서 추가할 작업 그룹을 선택하고 **작업 그룹 추가**를 선택합니다. 둘 이상의 예약에 작업 그룹을 할당할 수 없습니다.

   용량 예약의 세부 정보 페이지에는 추가한 작업 그룹이 나열됩니다. 해당 작업 그룹에서 실행되는 쿼리는 예약이 활성화될 때 예약한 용량을 사용합니다.

# 예약에서 작업 그룹 제거
<a name="capacity-management-removing-a-workgroup-from-a-reservation"></a>

더 이상 작업 그룹 전용 용량이 필요하지 않거나 작업 그룹을 고유한 예약으로 이동하려는 경우 언제든지 작업 그룹을 제거할 수 있습니다. 예약에서 작업 그룹을 제거하는 작업은 간단합니다. 예약에서 작업 그룹을 제거한 후 제거된 작업 그룹의 쿼리는 온디맨드 용량을 사용하도록 돌아가고 스캔한 테라바이트(TB)를 기준으로 요금이 청구됩니다.

**예약에서 하나 이상의 작업 그룹을 제거하려면**

1. 용량 예약의 세부 정보 페이지에서 제거하려는 작업 그룹을 선택합니다.

1. **작업 그룹 제거**를 선택합니다. **작업 그룹을 제거하시겠습니까?** 프롬프트에서는 작업 그룹이 예약에서 제거되기 전에 현재 활성 상태인 모든 쿼리가 완료된다는 메시지를 표시합니다.

1. **** 제거를 선택합니다. 용량 예약의 세부 정보 페이지에 제거된 작업 그룹이 더 이상 없다고 표시됩니다.

# 용량 예약 취소
<a name="capacity-management-cancelling-a-capacity-reservation"></a>

더 이상 용량 예약을 사용하지 않으려는 경우 취소할 수 있습니다. 예약을 사용하던 작업 그룹에서 여전히 실행 중인 쿼리는 완료할 수 있지만 작업 그룹의 다른 쿼리는 더 이상 예약을 사용하지 않습니다.

**참고**  
취소된 용량은 향후 재예약이 보장되지 않습니다. 또는 다른 예약(AWS 계정 또는 AWS 리전)으로 이전될 수 없습니다.

**용량 예약을 취소하려면**

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 콘솔 탐색 창이 표시되지 않으면 왼쪽의 확장 메뉴를 선택합니다.

1. **관리**, **용량 예약**을 선택합니다.

1. 용량 예약 목록에서 다음 중 하나를 수행합니다.
   + 예약 옆에 있는 버튼을 선택하고 **취소**를 선택합니다.
   + 예약 링크를 선택하고 **용량 예약 취소**를 선택합니다.

1. **용량 예약을 취소하시겠습니까?** 프롬프트에 **취소**를 입력하고 **용량 예약 취소**를 선택합니다.

   예약 상태가 **취소 중**으로 변경되고 진행 상황 배너에서 취소가 진행 중임을 알립니다.

   취소가 완료되면 용량 예약은 남아 있지만 상태는 **취소됨**으로 표시됩니다. 취소 후 45일이 지나면 예약이 삭제됩니다. 45일 동안 취소된 예약의 용도를 변경하거나 재사용할 수 없지만, 기록 참조를 위해 해당 태그를 참조하고 볼 수 있습니다.

# 용량 예약 삭제
<a name="capacity-management-deleting-a-capacity-reservation"></a>

취소된 용량 예약에 대한 모든 참조를 삭제하려면 예약을 삭제하면 됩니다. 예약을 삭제하려면 먼저 취소해야 합니다. 삭제된 예약은 계정에서 즉시 제거되고 ARN을 포함하여 더 이상 참조할 수 없습니다.

**용량 예약을 삭제하려면**

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 콘솔 탐색 창이 표시되지 않으면 왼쪽의 확장 메뉴를 선택합니다.

1. **관리**, **용량 예약**을 선택합니다.

1. 용량 예약 목록에서 다음 중 하나를 수행합니다.
   + 취소된 예약 옆에 있는 버튼을 선택하고 **작업**, **삭제**를 선택합니다.
   + 예약 링크를 선택하고 **삭제**를 선택합니다.

1. **용량 예약을 삭제하시겠습니까?** 프롬프트에서 **삭제**를 선택합니다.

   용량 예약이 삭제되었음을 알리는 배너가 나타납니다. 삭제된 예약은 더 이상 용량 예약 목록에 표시되지 않습니다.

# 용량 예약에 대한 IAM 정책
<a name="capacity-reservations-iam-policy"></a>

용량 예약에 대한 액세스를 제어하려면 리소스 수준 IAM 권한이나 자격 증명 기반 IAM 정책을 사용합니다. IAM 정책을 사용할 때마다 IAM 모범 사례를 따라야 합니다. 자세한 내용은 *IAM 사용 설명서*의 [IAM 보안 모범 사례](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)를 참조하세요.

다음은 Athena용 절차입니다.

IAM용 정보는 이 단원 끝부분에 나와 있는 링크를 참조하세요. JSON 용량 예약 정책 예제에 대한 자세한 내용은 [용량 예약 정책 예제](example-policies-capacity-reservations.md) 섹션을 참조하세요.

**용량 예약 정책을 생성하기 위해 IAM 콘솔에서 시각적 편집기를 사용하려면**

1. AWS Management Console에 로그인하여 [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)에서 IAM 콘솔을 엽니다.

1. 왼쪽 탐색 창에서 **정책**을 선택한 후 **정책 생성**을 선택합니다.

1. **시각적 편집기**(Visual editor) 탭에서 **서비스 선택**(Choose a service)을 선택합니다. 그런 다음 Athena를 선택하여 정책에 추가합니다.

1. **작업 선택**(Select actions)을 선택한 후 정책에 추가할 작업을 선택합니다. 시각적 편집기에 Athena에서 사용할 수 있는 작업이 표시됩니다. 자세한 내용은 *서비스 권한 부여 참조*에서 [Amazon Athena에 사용되는 작업, 리소스 및 조건 키](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonathena.html)를 참조하세요.

1. **작업 추가**를 선택하여 특정 작업을 입력하거나 와일드카드 문자(\$1)를 사용하여 여러 개의 작업을 지정합니다.

   기본적으로 사용자가 생성하는 정책은 사용자가 선택하는 작업을 허용합니다. Athena의 `capacity-reservation` 리소스에 대해 리소스 수준 권한을 지원하는 작업을 하나 이상 선택하면 편집기에 `capacity-reservation` 리소스가 나열됩니다.

1. **리소스**를 선택하여 정책에 대한 특정 용량 예약 리소스를 지정합니다. JSON 용량 예약 정책의 예제는 [용량 예약 정책 예제](example-policies-capacity-reservations.md) 섹션을 참조하세요.

1. 다음과 같이 `capacity-reservation` 리소스를 지정합니다.

   ```
   arn:aws:athena:<region>:<user-account>:capacity-reservation/<capacity-reservation-name>
   ```

1. **정책 검토**(Review policy)를 선택한 후 생성하려는 정책에 대한 **이름**(Name)과 **설명**(Description)(선택 사항)을 입력합니다. 정책 요약을 검토하여 의도한 권한을 부여했는지 확인합니다.

1. **정책 생성**(Create policy)을 선택하고 새로운 정책을 저장합니다.

1. ID 기반 정책을 사용자, 그룹 또는 역할에 연결합니다.

자세한 내용은 *서비스 권한 부여 참조*와 *IAM 사용 설명서*에서 다음 주제를 참조하세요.
+  [Amazon Athena에 사용되는 작업, 리소스 및 조건 키](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonathena.html) 
+  [시각적 편집기를 사용하여 정책 생성](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html#access_policies_create-visual-editor) 
+  [IAM 정책 추가 및 제거](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) 
+  [리소스에 대한 액세스 제어](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_controlling.html#access_controlling-resources) 

JSON 용량 예약 정책의 예제는 [용량 예약 정책 예제](example-policies-capacity-reservations.md) 섹션을 참조하세요.

Amazon Athena 작업의 전체 목록은 [Amazon Athena API 참조](https://docs.aws.amazon.com/athena/latest/APIReference/)의 API 작업 이름을 참조하세요.

# 용량 예약 정책 예제
<a name="example-policies-capacity-reservations"></a>

이 섹션에서는 용량 예약에서 다양한 작업을 활성화하는 데 사용할 수 있는 정책 예제를 설명합니다. IAM 정책을 사용할 때마다 IAM 모범 사례를 따라야 합니다. 자세한 내용은 *IAM 사용 설명서*의 [IAM 보안 모범 사례](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)를 참조하세요.

용량 예약은 Athena가 관리하는 IAM 리소스입니다. 따라서 용량 예약 정책에서 `capacity-reservation`을 입력으로 사용하는 작업을 사용할 경우 다음과 같이 용량 예약의 ARN을 지정해야 합니다.

```
"Resource": [arn:aws:athena:<region>:<user-account>:capacity-reservation/<capacity-reservation-name>]
```

여기에서 `<capacity-reservation-name>`은 용량 예약 이름입니다. 예를 들어 다음과 같이 `test_capacity_reservation`이라는 용량 예약에서 이를 리소스로 지정합니다.

```
"Resource": ["arn:aws:athena:us-east-1:123456789012:capacity-reservation/test_capacity_reservation"]
```

Amazon Athena 작업의 전체 목록은 [Amazon Athena API 참조](https://docs.aws.amazon.com/athena/latest/APIReference/)의 API 작업 이름을 참조하세요. IAM 정책에 대한 자세한 내용은 *IAM 사용 설명서*의 [시각적 편집기로 정책 생성](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html#access_policies_create-visual-editor)을 참조하세요.

**Example 용량 예약을 나열하는 정책 예제**  
다음 정책에서는 모든 사용자가 모든 용량 예약을 나열하도록 허용합니다.    
****  

```
{ 
    "Version":"2012-10-17",		 	 	  
    "Statement": [ 
        { 
            "Effect": "Allow", 
            "Action": [ 
                "athena:ListCapacityReservations" 
            ], 
            "Resource": "*" 
        } 
    ] 
}
```

**Example 관리 작업을 위한 정책 예제**  
다음 정책에서는 사용자가 `test_capacity_reservation` 용량 예약을 생성 및 취소하고 세부 정보를 확인하며 업데이트하도록 허용합니다. 또한 이 정책에서는 사용자가 `workgroupA` 및 `workgroupB`를 `test_capacity_reservation`에 할당하도록 허용합니다.    
****  

```
{ 
   "Version":"2012-10-17",		 	 	  
   "Statement":[ 
      { 
         "Effect": "Allow", 
         "Action": [ 
             "athena:CreateCapacityReservation", 
             "athena:GetCapacityReservation", 
             "athena:CancelCapacityReservation", 
             "athena:UpdateCapacityReservation", 
             "athena:GetCapacityAssignmentConfiguration", 
             "athena:PutCapacityAssignmentConfiguration" 
         ], 
         "Resource": [ 
             "arn:aws:athena:us-east-1:123456789012:capacity-reservation/test_capacity_reservation", 
             "arn:aws:athena:us-east-1:123456789012:workgroup/workgroupA", 
             "arn:aws:athena:us-east-1:123456789012:workgroup/workgroupB" 
         ] 
      } 
   ] 
}
```

# Athena 용량 예약 API
<a name="capacity-management-api-list"></a>

다음 목록에는 Athena 용량 예약 API 작업에 대한 참조 링크가 포함되어 있습니다. 데이터 구조 및 기타 Athena API 작업에 대해서는 [https://docs.aws.amazon.com/athena/latest/APIReference/](https://docs.aws.amazon.com/athena/latest/APIReference/)를 참조하세요.
+  [CancelCapacityReservation](https://docs.aws.amazon.com/athena/latest/APIReference/API_CancelCapacityReservation.html) 
+  [CreateCapacityReservation](https://docs.aws.amazon.com/athena/latest/APIReference/API_CreateCapacityReservation.html) 
+  [DeleteCapacityReservation](https://docs.aws.amazon.com/athena/latest/APIReference/API_DeleteCapacityReservation.html) 
+  [GetCapacityAssignmentConfiguration](https://docs.aws.amazon.com/athena/latest/APIReference/API_GetCapacityAssignmentConfiguration.html) 
+  [GetCapacityReservation](https://docs.aws.amazon.com/athena/latest/APIReference/API_GetCapacityReservation.html) 
+  [ListCapacityReservations](https://docs.aws.amazon.com/athena/latest/APIReference/API_ListCapacityReservations.html) 
+  [PutCapacityAssignmentConfiguration](https://docs.aws.amazon.com/athena/latest/APIReference/API_PutCapacityAssignmentConfiguration.html) 
+  [UpdateCapacityReservation](https://docs.aws.amazon.com/athena/latest/APIReference/API_UpdateCapacityReservation.html) 

# Athena 성능 최적화
<a name="performance-tuning"></a>

이 주제에서는 Athena 쿼리의 성능을 개선하기 위한 일반적인 정보와 구체적인 제안, 그리고 한도 및 리소스 사용량과 관련된 오류를 해결하는 방법을 제공합니다.

대체로 최적화는 서비스, 쿼리, 데이터 구조 범주로 그룹화할 수 있습니다. 서비스 수준, 쿼리 작성 방법, 데이터 및 테이블 구조 등에 대한 결정이 모두 성능에 영향을 미칠 수 있습니다.

**Topics**
+ [서비스 사용 최적화](performance-tuning-service-level-considerations.md)
+ [쿼리 최적화](performance-tuning-query-optimization-techniques.md)
+ [데이터 최적화](performance-tuning-data-optimization-techniques.md)
+ [열 기반 스토리지 형식 사용](columnar-storage.md)
+ [분할 및 버킷팅 사용](ctas-partitioning-and-bucketing.md)
+ [데이터 파티셔닝](partitions.md)
+ [Amazon Athena에서 파티션 프로젝션 사용](partition-projection.md)
+ [Amazon S3 제한 방지](performance-tuning-s3-throttling.md)
+ [추가 리소스](performance-tuning-additional-resources.md)

# 서비스 사용 최적화
<a name="performance-tuning-service-level-considerations"></a>

서비스 수준 고려 사항에는 계정당 실행하는 워크로드 수, Athena뿐만 아니라 전체 서비스에 대한 서비스 할당량, '리소스 부족' 오류를 줄이는 방법에 대한 고려 등이 포함됩니다.

**Topics**
+ [동일한 계정 내에서 여러 워크로드 운영](#performance-tuning-service-quotas)
+ ['리소스 부족' 오류 줄이기](#performance-tuning-resource-limits)

## 동일한 계정 내에서 여러 워크로드 운영
<a name="performance-tuning-service-quotas"></a>

Athena는 할당량을 사용하여 계정 수준에서 쿼리 동시성 및 API 요청 속도를 제한합니다. 이러한 할당량을 초과하면 실행 중 또는 제출 시 쿼리가 실패할 수 있습니다. 이러한 할당량에 대한 자세한 내용은 [Service Quotas](service-limits.md) 섹션을 참조하세요.

동일한 AWS 계정 내에서 여러 워크로드를 운영하는 경우 워크로드는 동일한 계정 수준 할당량에 대해 경합합니다. 예를 들어, 한 워크로드에서 예상치 못한 쿼리 버스트가 발생하면 같은 계정에서 실행되는 다른 워크로드의 대기열 시간이 늘어나거나 최악의 경우 스로틀링으로 인해 쿼리 제출이 실패할 수 있습니다.

CloudWatch를 사용하여 그래프 및 대시보드를 통해 서비스 사용량을 모니터링하는 것이 좋습니다. 또한 사용량이 동시 쿼리 서비스 할당량에 근접하면 알려주는 CloudWatch 경보를 구성하여 할당량 한도에 도달하기 전에 조치를 취할 수 있습니다. 자세한 내용은 [CloudWatch를 사용하여 Athena 사용량 지표 모니터링](monitoring-athena-usage-metrics.md) 섹션을 참조하세요.

계정 내에서 쿼리 동시성을 제어하고 워크로드를 격리하려면 용량 예약을 사용합니다. 용량 예약은 단일 계정 내에서 전용 쿼리 처리 용량을 제공합니다. 용량은 데이터 처리 단위(DPU)로 측정되며 쿼리 동시성을 증가 또는 감소하기 위해 추가 또는 제거할 수 있습니다. 용량 예약을 사용하면 하나 이상의 작업 그룹에 용량을 할당하여 계정 내의 워크로드를 서로 격리할 수 있습니다. 자세한 내용은 [쿼리 처리 용량 관리](capacity-management.md) 섹션을 참조하세요.

관련 없는 여러 워크로드를 서로 다른 AWS 계정으로 분리해야 하지만(예: 개발 환경을 프로덕션 환경에서 격리) 이 접근 방식은 쿼리 동시성을 높이는 확장 가능한 방법을 제공하지 않습니다. 대신 용량 예약을 사용하여 단일 계정 내에서 쿼리 처리 요구 사항을 관리하고 확장할 수 있습니다.

### 다른 서비스의 할당량 고려
<a name="performance-tuning-quotas-in-other-services"></a>

Athena에서 쿼리를 실행할 때 할당량을 적용하는 다른 서비스를 호출할 수 있습니다. 쿼리 실행 중에 Athena는 AWS Glue Data Catalog, Amazon S3, 기타 AWS 서비스(예: IAM 및 AWS KMS)에 대한 API 호출을 수행할 수 있습니다. [페더레이션된 쿼리](federated-queries.md)를 사용하는 경우 Athena는 AWS Lambda도 직접적으로 호출합니다. 이러한 모든 서비스에는 초과할 수 있는 자체 한도 및 할당량이 있습니다. 쿼리 실행 시 이러한 서비스에서 오류가 발생하면 쿼리에 실패하고 소스 서비스에서도 오류가 발생합니다. 복구 가능한 오류는 재시도되지만 문제가 제때 해결되지 않으면 쿼리에 실패할 수 있습니다. 오류 메시지를 자세히 읽고 Athena에서 보낸 것인지, 다른 서비스에서 보낸 것인지 확인합니다. 이 성능 조정 섹션에서는 관련 오류 중 일부를 다룹니다.

Amazon S3 서비스 할당량으로 인한 오류 해결에 대한 자세한 내용은 이 문서에서 나중에 나오는 [너무 많은 수의 파일 방지](performance-tuning-data-optimization-techniques.md#performance-tuning-avoid-having-too-many-files) 섹션을 참조하세요. Amazon S3 성능 최적화에 대한 자세한 내용은 *Amazon S3 사용 설명서*의 [모범 사례 설계 패턴: Amazon S3 성능 최적화](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html)를 참조하세요.

## '리소스 부족' 오류 줄이기
<a name="performance-tuning-resource-limits"></a>

Athena는 분산 쿼리 엔진에서 쿼리를 실행합니다. 쿼리를 제출하면 Athena 엔진 쿼리 플래너에서 쿼리를 실행하는 데 필요한 컴퓨팅 용량을 추정하고 적절히 컴퓨팅 노드 클러스터를 준비합니다. DDL 쿼리와 같은 일부 쿼리는 하나의 노드에서만 실행됩니다. 대규모 데이터 세트에 대한 복잡한 쿼리는 훨씬 더 큰 클러스터에서 실행됩니다. 노드는 동일한 메모리, CPU 및 디스크 구성을 사용하여 균일합니다. Athena는 보다 까다로운 쿼리를 처리하기 위해 스케일 업이 아닌, 스케일 아웃으로 확장합니다.

쿼리 요구량이 쿼리를 실행하는 클러스터에서 사용할 수 있는 리소스를 초과하는 경우가 있습니다. 이 경우 쿼리에 실패하고 Query exhausted resources at this scale factor 오류가 발생합니다.

일반적으로 가장 많이 소진되는 리소스는 메모리이지만, 디스크 공간이 소진되는 경우도 드물게 있습니다. 메모리 오류는 엔진에서 조인 또는 창 함수를 수행할 때 흔히 발생하지만 개별 개수와 집계에서 발생할 수도 있습니다.

일단 'out of resource' 오류로 쿼리에 실패했더라도 다시 실행했을 때 성공할 수도 있습니다. 쿼리 실행은 결정적이지 않습니다. 데이터를 로드하는 데 걸리는 시간, 중간 데이터 세트가 노드에 분산되는 방식 등의 요인으로 인해 리소스 사용량이 달라질 수 있습니다. 예를 들어 두 테이블을 조인하고 조인 조건의 값 분포에서 편차가 큰 쿼리를 가정합니다. 이러한 쿼리는 대부분의 경우 성공할 수 있지만, 가장 일반적인 값이 동일한 노드에서 처리되면 실패합니다.

쿼리가 사용 가능한 리소스를 초과하지 않도록 하려면 이 문서에 언급된 성능 튜닝 팁을 사용합니다. 특히 사용 가능한 리소스를 소진하는 쿼리를 최적화하는 방법에 대한 팁은 [조인 최적화](performance-tuning-query-optimization-techniques.md#performance-tuning-optimizing-joins), [창 함수의 범위를 축소 또는 제거](performance-tuning-query-optimization-techniques.md#performance-tuning-optimizing-window-functions) 및 [근사치를 사용하여 쿼리 최적화](performance-tuning-query-optimization-techniques.md#performance-tuning-optimizing-queries-by-using-approximations) 섹션을 참조하세요.

# 쿼리 최적화
<a name="performance-tuning-query-optimization-techniques"></a>

이 섹션에 설명된 쿼리 최적화 기술을 사용하면 쿼리를 더 빠르게 실행하거나 Athena의 리소스 한도를 초과하는 쿼리 문제를 해결할 수 있습니다.

## 조인 최적화
<a name="performance-tuning-optimizing-joins"></a>

분산 쿼리 엔진에서 조인을 실행하는 다양한 전략이 있습니다. 가장 일반적인 두 가지는 분산 해시 조인과 복잡한 조인 조건을 사용하는 쿼리입니다.

### 분산 해시 조인에서 대형 테이블은 왼쪽에, 소형 테이블은 오른쪽에 배치합니다.
<a name="performance-tuning-distributed-hash-join"></a>

가장 일반적인 유형의 조인은 관계 비교 연산자를 조인 조건으로 사용합니다. Athena는 이 유형의 조인을 분산 해시 조인으로 실행합니다.

분산 해시 조인에서 엔진은 조인 측 중 하나에서 조회 테이블(해시 테이블)을 빌드합니다. 이 조인 측을 *빌드 측*이라고 합니다. 빌드 측 레코드는 여러 노드에 분산되어 있습니다. 각 노드는 해당 하위 세트에 대한 조회 테이블을 빌드합니다. 그러면 조인의 다른 측(*프로브 측*)이 노드를 통해 스트리밍됩니다. 프로브 측의 레코드는 빌드 측과 동일한 방식으로 노드에 분산됩니다. 이를 통해 각 노드는 자체 조회 테이블에서 일치하는 레코드를 조회하여 조인을 수행할 수 있습니다.

조인의 빌드 측에서 생성된 조회 테이블이 메모리에 맞지 않으면 쿼리에 실패할 수 있습니다. 빌드 측의 전체 크기가 사용 가능한 메모리보다 작더라도 레코드 분산 편차가 너무 크면 쿼리에 실패할 수 있습니다. 극단적인 경우 모든 레코드의 조인 조건 값이 같고 단일 노드의 메모리에 맞아야 할 수도 있습니다. 값 세트가 동일한 노드로 전송되고 값의 합계가 사용 가능한 메모리를 초과하면 편차가 적은 쿼리라도 실패할 수 있습니다. 노드는 레코드를 디스크로 유출할 수 있지만 유출 시 쿼리 실행 속도가 느려지고 이 방법으로는 쿼리 실패를 막지 못할 수도 있습니다.

Athena는 더 큰 관계를 프로브 측으로 사용하고 더 작은 관계를 빌드 측으로 사용하도록 조인 순서를 변경하려고 합니다. 그러나 Athena는 테이블의 데이터를 관리하지 않기 때문에 정보가 제한적이며 종종 첫 번째 테이블이 더 크고 두 번째 테이블은 더 작다고 가정해야 합니다.

관계 기반 조인 조건을 사용하여 조인을 작성하는 경우 `JOIN` 키워드 왼쪽의 테이블이 프로브 측이고 오른쪽 테이블이 빌드 측이라고 가정합니다. 오른쪽 테이블(빌드 측)이 더 작은 테이블인지 확인합니다. 조인의 빌드 측 크기를 메모리에 맞도록 작게 설정할 수 없다면 빌드 테이블의 하위 세트를 조인하는 쿼리를 여러 번 실행하는 방법을 고려합니다.

### EXPLAIN을 사용하여 복잡한 조인이 있는 쿼리 분석
<a name="performance-tuning-other-join-types"></a>

복잡한 조인 조건의 쿼리(예: `LIKE`, `>` 또는 다른 연산자를 사용하는 쿼리)는 종종 계산이 까다롭습니다. 최악의 경우에는 조인의 한쪽에 있는 모든 레코드를 조인 반대쪽에 있는 모든 레코드와 비교해야 합니다. 실행 시간은 레코드 수의 제곱에 비례하여 증가하므로 이러한 쿼리는 최대 실행 시간을 초과할 위험이 있습니다.

Athena에서 쿼리를 실행하는 방법을 미리 확인하려면 `EXPLAIN` 문을 사용할 수 있습니다. 자세한 내용은 [Athena에서 EXPLAIN 및 EXPLAIN ANALYZE 사용](athena-explain-statement.md) 및 [Athena EXPLAIN 문 결과 이해](athena-explain-statement-understanding.md)(을)를 참조하세요.

## 창 함수의 범위를 축소 또는 제거
<a name="performance-tuning-optimizing-window-functions"></a>

창 함수는 리소스를 많이 사용하는 작업이므로 쿼리 실행 속도가 느려지거나 쿼리에 실패하고 Query exhausted resources at this scale factor 메시지가 표시될 수 있습니다. 창 함수는 결과를 계산하기 위해 작업하는 모든 레코드를 메모리에 보관합니다. 창 크기가 너무 크면 창 함수의 메모리가 부족해질 수 있습니다.

사용 가능한 메모리 한도 내에서 쿼리를 실행하려면 창 함수가 작동하는 창 크기를 줄입니다. 이렇게 하기 위해 `PARTITIONED BY` 절을 추가하거나 기존 파티셔닝 절의 범위를 좁힐 수 있습니다.

### 창이 아닌 함수를 사용
<a name="performance-tuning-optimizing-window-functions-rewrite"></a>

창 함수가 있는 쿼리를 창 함수 없이 다시 작성할 수도 있습니다. 예를 들어 상위 `N`개 레코드를 찾기 위해 `row_number`를 사용하는 대신, `ORDER BY` 및 `LIMIT`를 사용할 수 있습니다. 레코드 중복을 제거하기 위해 `row_number` 또는 `rank`를 사용하는 대신, [max\$1by](https://trino.io/docs/current/functions/aggregate.html#max_by), [min\$1by](https://trino.io/docs/current/functions/aggregate.html#min_by), [arbitrary](https://trino.io/docs/current/functions/aggregate.html#arbitrary)와 같은 집계 함수를 사용할 수 있습니다.

예를 들어 센서의 업데이트가 포함된 데이터 세트가 있다고 가정합니다. 센서는 주기적으로 배터리 상태를 보고하고 위치와 같은 일부 메타데이터를 포함합니다. 각 센서의 마지막 배터리 상태와 위치를 확인하려는 경우 다음 쿼리를 사용할 수 있습니다.

```
SELECT sensor_id,
       arbitrary(location) AS location,
       max_by(battery_status, updated_at) AS battery_status
FROM sensor_readings
GROUP BY sensor_id
```

위치와 같은 메타데이터는 모든 레코드에서 동일하므로 `arbitrary` 함수를 사용하여 그룹에서 임의의 값을 선택할 수 있습니다.

마지막 배터리 상태를 가져오기 위해 `max_by` 함수를 사용할 수 있습니다. `max_by` 함수는 다른 열의 최댓값을 찾은 레코드에서 열의 값을 선택합니다. 이 경우 그룹 내 마지막 업데이트 시간과 함께 레코드에서 배터리 상태를 반환합니다. 이 쿼리는 창 함수를 사용하는 동등한 쿼리보다 실행 속도가 빠르고 메모리 사용량도 적습니다.

## 집계 최적화
<a name="performance-tuning-optimizing-aggregations"></a>

Athena는 집계를 수행할 때 `GROUP BY` 절의 열을 사용하여 여러 워커 노드에서 레코드를 분산시킵니다. 레코드를 그룹과 일치시키는 작업을 최대한 효율적으로 수행하기 위해 노드에서는 레코드를 메모리에 보관하지만 필요한 경우 디스크로 유출합니다.

`GROUP BY` 절에서 중복 열을 포함하지 않는 것도 좋은 방법입니다. 열 수가 적을수록 필요한 메모리도 적어지기 때문에 더 적은 열을 사용하여 그룹을 설명하는 쿼리가 보다 효율적입니다. 또한 숫자 열은 문자열보다 메모리를 덜 사용합니다. 예를 들어 숫자 카테고리 ID와 카테고리 이름이 모두 있는 데이터 세트를 집계하는 경우 `GROUP BY` 절에서 카테고리 ID 열만 사용합니다.

열이 집계 표현식 또는 `GROUP BY` 절의 일부여야 한다는 점을 처리하기 위해 쿼리에서 `GROUP BY` 절에 열을 포함하기도 합니다. 이 규칙을 따르지 않으면 다음과 같은 오류 메시지가 나타날 수 있습니다.

 EXPRESSION\$1NOT\$1AGGREGATE: line 1:8: 'category' must be an aggregate expression or appear in GROUP BY clause 

`GROUP BY` 절에 중복 열을 추가할 필요가 없도록 다음 예제와 같이 [arbitrary](https://trino.io/docs/current/functions/aggregate.html#arbitrary) 함수를 사용할 수 있습니다.

```
SELECT country_id,
       arbitrary(country_name) AS country_name,
       COUNT(*) AS city_count
FROM world_cities
GROUP BY country_id
```

`ARBITRARY` 함수는 그룹에서 임의의 값을 반환합니다. 이 함수는 그룹 내 모든 레코드에서 열 값이 같지만 값으로 그룹을 식별하지 못하는 경우에 유용합니다.

## 상위 N개 쿼리 최적화
<a name="performance-tuning-optimizing-top-n-queries"></a>

`ORDER BY` 절은 정렬된 순서로 쿼리 결과를 반환합니다. Athena는 분산 정렬을 사용하여 여러 노드에서 정렬 작업을 병렬로 실행합니다.

결과를 정렬할 필요가 없는 경우 `ORDER BY` 절을 추가하지 않습니다. 또한 필요한 쿼리가 아닌 경우 내부 쿼리에 `ORDER BY`를 추가하지 않습니다. 대부분의 경우 쿼리 플래너에서 중복 정렬을 제거할 수 있지만, 보장되지는 않습니다. 이 규칙의 예외는 내부 쿼리가 상위 `N`개 작업(예: 최근 `N`개 또는 가장 일반적인 `N`개 값 찾기)을 수행하는 경우입니다.

Athena에서 `ORDER BY`가 `LIMIT`와 함께 나타나는 경우 상위 `N`개 쿼리를 실행 중이고 적절히 전용 작업을 사용하는 것입니다.

**참고**  
Athena에서 상위 `N`개를 사용하는 `row_number`와 같은 창 함수를 종종 탐지할 수 있어도 `ORDER BY` 및 `LIMIT`를 사용하는 더 간단한 버전을 사용하는 것이 좋습니다. 자세한 내용은 [창 함수의 범위를 축소 또는 제거](#performance-tuning-optimizing-window-functions) 섹션을 참조하세요.

## 필수 열만 포함
<a name="performance-tuning-include-only-required-columns"></a>

열이 필요하지 않은 경우 쿼리에 포함하지 않습니다. 쿼리에서 처리해야 하는 데이터가 적을수록 실행 속도가 빨라집니다. 그러면 필요한 메모리 양과 노드 사이에서 전송해야 하는 데이터 양이 모두 줄어듭니다. 열 기반 파일 형식을 사용하는 경우 열 수를 줄이면 Amazon S3에서 읽는 데이터 양도 줄어듭니다.

Athena에서 결과의 열 수에 대한 구체적인 한도는 없지만 쿼리 실행 방식에 따라 가능한 총 열 크기가 제한됩니다. 총 열 크기에는 이름 및 유형이 포함됩니다.

예를 들어 관계 설명자의 크기 제한을 초과하는 관계로 인해 다음 오류가 발생합니다.

 GENERIC\$1INTERNAL\$1ERROR: io.airlift.bytecode.CompilationException 

이 문제를 해결하려면 쿼리의 열 개수를 줄이거나 하위 쿼리를 만들고 더 적은 양의 데이터를 검색하는 `JOIN`을 사용합니다. 가장 바깥쪽 쿼리에서 `SELECT *`를 수행하는 쿼리가 있는 경우 `*`를 필요한 열만 포함하는 목록으로 변경해야 합니다.

## 근사치를 사용하여 쿼리 최적화
<a name="performance-tuning-optimizing-queries-by-using-approximations"></a>

Athena에서는 개별 값, 가장 빈번한 값, 백분위수(근사 중앙값 포함) 계산 및 히스토그램 생성을 위한 [근사 집계 함수](https://trino.io/docs/current/functions/aggregate.html#appro)를 지원합니다. 정확한 값이 필요하지 않은 경우 이 함수를 사용합니다.

`COUNT(DISTINCT col)` 연산과 달리 [approx\$1distinct](https://trino.io/docs/current/functions/aggregate.html#approx_distinct)는 메모리를 훨씬 적게 사용하고 실행 속도도 더 빠릅니다. 마찬가지로 [histogram](https://trino.io/docs/current/functions/aggregate.html#histogram) 대신 [numeric\$1histogram](https://trino.io/docs/current/functions/aggregate.html#numeric_histogram)을 사용하면 근사치 계산 방법을 사용하므로 메모리가 적게 소비됩니다.

## LIKE 최적화
<a name="performance-tuning-optimizing-like"></a>

`LIKE`를 사용하여 일치하는 문자열을 찾을 수 있지만 문자열이 길면 컴퓨팅 용량을 많이 소비합니다. [regexp\$1like](https://trino.io/docs/current/functions/regexp.html#regexp_like) 함수는 대부분의 경우에 더 빠른 대안이며 유연성이 더 뛰어납니다.

찾고 있는 하위 문자열을 고정하여 검색을 최적화할 수도 있습니다. 예를 들어 접두사를 찾으려면 '%*substr*% 대신 '*substr*%'를 사용하는 것이 훨씬 좋습니다. 또는 `regexp_like`를 사용하는 경우 '^*substr*'을 사용합니다.

## UNION 대신 UNION ALL 사용
<a name="performance-tuning-use-union-all-instead-of-union"></a>

 `UNION ALL` 및 `UNION`은 두 쿼리의 결과를 하나의 결과로 결합하는 두 가지 방법입니다. `UNION ALL`은 첫 번째 쿼리의 레코드를 두 번째 쿼리와 연결합니다. `UNION`은 동일한 작업을 수행하되 중복된 항목도 제거합니다. `UNION`은 모든 레코드를 처리하고 중복을 찾아야 하므로 메모리와 컴퓨팅 용량을 많이 소비하지만, `UNION ALL`은 비교적 속도가 빠른 연산입니다. 레코드의 중복을 제거해야 하는 경우가 아니라면 최상의 성능을 위해 `UNION ALL`을 사용합니다.

## 결과 세트가 큰 경우 UNLOAD 사용
<a name="performance-tuning-use-unload-for-large-result-sets"></a>

쿼리 결과가 커질 것으로 예상되는 경우(예: 수만 행 이상) UNLOAD를 사용하여 결과를 내보냅니다. 대부분의 경우 이 방법이 일반 쿼리를 실행하는 것보다 빠르며 `UNLOAD`를 사용하는 경우 출력을 더 잘 제어할 수 있습니다.

쿼리 실행이 완료되면 Athena는 결과를 압축되지 않은 단일 CSV 파일로 Amazon S3에 저장합니다. 단, 결과가 압축되지 않고 연산을 병렬화할 수 없으므로 `UNLOAD`보다 시간이 오래 걸립니다. 반면 `UNLOAD`는 워커 노드에서 직접 결과를 쓰고 컴퓨팅 클러스터의 병렬 처리를 최대한 활용합니다. 또한 결과를 압축된 형식과 JSON, Parquet 등의 다른 파일 형식으로 기록하도록 `UNLOAD`를 구성할 수 있습니다.

자세한 내용은 [UNLOAD](unload.md) 섹션을 참조하세요.

## CTAS 또는 Glue ETL을 사용하여 자주 사용되는 집계 구체화
<a name="performance-tuning-use-ctas-or-glue-etl-to-materialize-frequently-used-aggregations"></a>

쿼리 '구체화'는 사전 계산된 복잡한 쿼리 결과(예: 집계 및 조인)를 후속 쿼리에서 재사용할 수 있도록 저장하여 쿼리 성능을 가속화하는 방법입니다.

많은 쿼리에 동일한 조인 및 집계가 포함된 경우 공통 하위 쿼리를 새 테이블로 구체화하고 해당 테이블에 대해 쿼리를 실행할 수 있습니다. [쿼리 결과에서 테이블 생성(CTAS)](ctas.md) 또는 [Glue ETL](https://aws.amazon.com/glue)과 같은 전용 ETL 도구를 사용하여 새 테이블을 생성할 수 있습니다.

예를 들어 주문 데이터 세트의 다양한 측면을 보여주는 위젯을 포함하는 대시보드를 가정합니다. 각 위젯에는 자체 쿼리가 있지만 모든 쿼리가 동일한 조인 및 필터를 공유합니다. 주문 테이블은 라인 품목 테이블과 결합되며 지난 3개월만 표시하는 필터가 있습니다. 이러한 쿼리의 일반적인 기능을 식별하면 위젯에서 사용할 수 있는 새 테이블을 생성할 수 있습니다. 그러면 중복이 줄어들고 성능이 향상됩니다. 단점은 새 테이블을 최신 상태로 유지해야 한다는 점입니다.

## 쿼리 결과 재사용
<a name="performance-tuning-reuse-query-results"></a>

동일한 쿼리는 짧은 시간 안에 여러 번 실행하는 것이 일반적입니다. 예를 들어 여러 사람이 같은 데이터 대시보드를 열 때 이런 상황이 발생할 수 있습니다. 이 경우 쿼리를 실행할 때 이전에 계산된 결과를 재사용하도록 Athena에 지시할 수 있습니다. 재사용할 결과의 최대 수명을 지정합니다. 이전에 동일한 쿼리가 해당 기간 안에 실행된 경우 Athena는 쿼리를 다시 실행하는 대신 해당 결과를 반환합니다. 자세한 내용은 *Amazon Athena 사용 설명서*의 [Athena에서 쿼리 결과 재사용](reusing-query-results.md) 섹션 및 *AWS 빅 데이터 블로그*의 [Reduce cost and improve query performance with Amazon Athena Query Result Reuse](https://aws.amazon.com/blogs/big-data/reduce-cost-and-improve-query-performance-with-amazon-athena-query-result-reuse/)를 참조하세요.

# 데이터 최적화
<a name="performance-tuning-data-optimization-techniques"></a>

성능은 쿼리뿐만 아니라 데이터 세트의 구성 방식, 데이터 세트가 사용하는 파일 형식 및 압축에 따라 달라집니다.

## 데이터 파티셔닝
<a name="performance-tuning-partition-your-data"></a>

파티셔닝은 테이블을 여러 부분으로 나누고 날짜, 국가 또는 지역과 같은 속성을 기반으로 관련 데이터를 함께 보관합니다. 파티션 키는 가상 열 역할을 합니다. 테이블 생성 시 파티션 키를 정의하고 쿼리 필터링에 해당 파티션 키를 사용합니다. 파티션 키 열을 필터링하면 일치하는 파티션의 데이터만 읽습니다. 예를 들어 데이터 세트가 날짜별로 파티셔닝되어 있고 쿼리에 지난 주에만 일치하는 필터가 있는 경우 지난 주의 데이터만 읽습니다. 파티셔닝에 대한 자세한 내용은 [데이터 파티셔닝](partitions.md) 섹션을 참조하세요.

## 쿼리를 지원하는 파티션 키를 선택합니다.
<a name="performance-tuning-pick-partition-keys-that-will-support-your-queries"></a>

파티셔닝은 쿼리 성능에 큰 영향을 미치므로 데이터 세트와 테이블을 설계할 때 파티셔닝을 신중하게 고려해야 합니다. 파티션 키가 너무 많으면 너무 작은 파일과 너무 많은 파일로 데이터 세트가 조각화될 수 있습니다. 반대로 파티션 키가 너무 적거나 전혀 파티셔닝하지 않으면 쿼리에서 필요 이상으로 많은 데이터를 스캔합니다.

### 드문 쿼리에 대한 최적화 방지
<a name="performance-tuning-avoid-optimizing-for-rare-queries"></a>

가장 일반적인 쿼리에 대해 최적화하고 드문 쿼리에 대해서는 최적화하지 않는 것이 좋습니다. 예를 들어 쿼리가 일 단위로 표시되는 경우 일부 쿼리가 해당 수준으로 필터링되더라도 시간 단위로 파티셔닝하지 않습니다. 데이터에 세밀한 수준의 타임스탬프 열이 있는 경우 시간 단위로 필터링하는 드문 쿼리에서 이 타임스탬프 열을 사용할 수 있습니다. 드물지만 필요 이상으로 데이터를 조금 더 많이 스캔하더라도 드문 상황에 대비해 전체 성능을 낮추는 작업은 일반적으로 좋은 절충안이 아닙니다.

쿼리에서 스캔해야 하는 데이터를 줄여 성능을 개선하려면 열 기반 파일 형식을 사용하고 레코드를 정렬된 상태로 유지합니다. 시간 단위로 파티셔닝하는 대신 타임스탬프를 기준으로 레코드를 정렬합니다. 기간이 짧은 쿼리의 경우 타임스탬프를 기준으로 정렬하는 방법이 시간 단위로 파티셔닝하는 것만큼 효율적입니다. 또한 타임스탬프를 기준으로 정렬해도 일반적으로 일 단위로 계산되는 기간에서는 쿼리 성능이 저하되지 않습니다. 자세한 내용은 [열 기반 파일 형식 사용](#performance-tuning-use-columnar-file-formats) 섹션을 참조하세요.

수만 개의 파티션이 있는 테이블에 대한 쿼리의 경우 모든 파티션 키에 조건자가 있으면 성능이 개선됩니다. 가장 일반적인 쿼리에 대해 파티셔닝 체계를 설계해야 하는 또 다른 이유가 바로 여기에 있습니다. 자세한 내용은 [관계 조건자로 파티션 쿼리](#performance-tuning-query-partitions-by-equality) 섹션을 참조하세요.

## 파티션 프로젝션 사용
<a name="performance-tuning-use-partition-projection"></a>

파티션 프로젝션은 파티션 정보를 AWS Glue Data Catalog에 저장하지 않고 AWS Glue에서 테이블 속성의 규칙으로 저장하는 Athena 기능입니다. Athena에서 파티션 프로젝션으로 구성된 테이블에 대한 쿼리를 계획할 때 테이블의 파티션 프로젝션 규칙을 읽습니다. Athena에서는 AWS Glue Data Catalog에서 파티션을 조회하는 대신, 쿼리와 규칙을 기반으로 메모리에서 읽을 파티션을 계산합니다.

파티션 프로젝션은 파티션 관리를 단순화하는 것 외에도, 파티션 수가 많은 데이터 세트의 성능을 개선할 수 있습니다. 쿼리에 파티션 키의 특정 값 대신 범위가 포함된 경우 카탈로그에서 일치하는 파티션을 조회할 때 파티션이 많을수록 시간이 더 오래 걸립니다. 파티션 프로젝션을 사용하면 카탈로그로 이동하지 않고도 메모리에서 필터를 계산할 수 있으며 속도도 훨씬 더 빠를 수 있습니다.

경우에 따라 파티션 프로젝션으로 인해 성능이 저하되기도 합니다. 한 가지 예로 '스파스' 테이블이 이에 해당합니다. 스파스 테이블에는 파티션 프로젝션 구성에서 설명하는 파티션 키 값의 모든 순열에 대한 데이터가 포함되지 않습니다. 스파스 테이블을 사용하면 쿼리에서 계산된 파티션 세트와 파티션 프로젝션 구성은 데이터가 없어도 모두 Amazon S3에 나열됩니다.

파티션 프로젝션을 사용하는 경우 모든 파티션 키에 조건자를 포함해야 합니다. 불필요한 Amazon S3 나열을 피하려면 가능한 값의 범위를 좁힙니다. 값의 범위가 백만 개인 파티션 키와 해당 파티션 키에 필터가 없는 쿼리를 가정합니다. 쿼리를 실행하기 위해 Athena는 최소 백만 건의 Amazon S3 나열 작업을 수행해야 합니다. 파티션 프로젝션을 사용하든, 카탈로그에 파티션 정보를 저장하든 관계없이 특정 값을 쿼리할 때 쿼리 속도가 가장 빠릅니다. 자세한 내용은 [관계 조건자로 파티션 쿼리](#performance-tuning-query-partitions-by-equality) 섹션을 참조하세요.

파티션 프로젝션에 대해 테이블을 구성하는 경우 지정하는 범위가 적절해야 합니다. 쿼리에서 파티션 키에 조건자가 포함되지 않는 경우 해당 키 범위의 모든 값이 사용됩니다. 데이터 세트가 특정 날짜에 생성된 경우 해당 날짜를 날짜 범위의 시작점으로 사용합니다. 종료 날짜 범위로는 `NOW`를 사용합니다. 값의 수가 많은 숫자 범위는 피하고 대신 [injected](partition-projection-dynamic-id-partitioning.md#partition-projection-injection) 형식을 사용하는 것이 좋습니다.

파티션 프로젝션에 대한 자세한 내용은 [Amazon Athena에서 파티션 프로젝션 사용](partition-projection.md) 단원을 참조하세요.

## 파티션 인덱스 사용
<a name="performance-tuning-use-partition-indexes"></a>

파티션 인덱스는 파티션 수가 많은 테이블의 파티션 조회 성능을 개선하는 AWS Glue Data Catalog의 기능입니다.

카탈로그에서 파티션 목록은 관계형 데이터베이스의 테이블과 같습니다. 테이블에는 파티션 키에 해당하는 열과 파티션 위치에 해당하는 추가 열이 있습니다. 파티셔닝 테이블을 쿼리하는 경우 이 테이블을 스캔하면 파티션 위치를 조회합니다.

관계형 데이터베이스와 마찬가지로 인덱스를 추가하여 쿼리 성능을 높일 수 있습니다. 여러 인덱스를 추가하여 다양한 쿼리 패턴을 지원할 수 있습니다. AWS Glue Data Catalog 파티션 인덱스는 관계 연산자와 비교 연산자(예: `>`, `>=`, `<`)를 `AND` 연산자로 결합하여 모두 지원합니다. 자세한 내용은 *AWS Glue 개발자 안내서*의 [Working with partition indexes in AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/partition-indexes.html) 및 *AWS 빅 데이터 블로그*의 [Improve Amazon Athena query performance using AWS Glue Data Catalog partition indexes](https://aws.amazon.com/blogs/big-data/improve-amazon-athena-query-performance-using-aws-glue-data-catalog-partition-indexes/)를 참조하세요.

## 파티션 키 유형으로 항상 STRING 사용
<a name="performance-tuning-always-use-string-as-the-type-for-partition-keys"></a>

파티션 키에서 쿼리하는 경우 파티션 필터링을 AWS Glue로 푸시다운하려면 Athena에 `STRING` 유형의 파티션 키가 필요합니다. 파티션 수가 적지 않은 경우 다른 유형을 사용하면 성능이 저하될 수 있습니다. 파티션 키 값이 날짜나 숫자와 비슷한 경우 쿼리에서 적절한 유형으로 변환합니다.

## 오래되고 비어 있는 파티션 제거
<a name="performance-tuning-remove-old-and-empty-partitions"></a>

Amazon S3의 파티션에서 데이터를 제거하는 경우(예: Amazon S3 [수명 주기](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html) 사용) AWS Glue Data Catalog에서도 파티션 항목을 제거해야 합니다. 쿼리 계획 중에 쿼리와 일치하는 모든 파티션이 Amazon S3에 나열됩니다. 빈 파티션이 많은 경우 이러한 파티션을 나열하며 발생하는 오버헤드로 인해 성능이 저하될 수 있습니다.

또한 수천 개의 파티션이 있는 경우 더 이상 관련이 없는 오래된 데이터에 대한 파티션 메타데이터를 제거하는 것이 좋습니다. 예를 들어 쿼리에서 1년이 넘은 데이터를 확인하지 않는 경우 오래된 파티션에 대한 파티션 메타데이터를 주기적으로 제거할 수 있습니다. 파티션 수가 수만 개로 늘어나는 경우 사용하지 않는 파티션을 제거하면 모든 파티션 키에서 조건자를 포함하지 않는 쿼리의 속도를 높일 수 있습니다. 쿼리에서 모든 파티션 키에 조건자를 포함하는 방법에 대한 자세한 내용은 [관계 조건자로 파티션 쿼리](#performance-tuning-query-partitions-by-equality) 섹션을 참조하세요

## 관계 조건자로 파티션 쿼리
<a name="performance-tuning-query-partitions-by-equality"></a>

모든 파티션 키에서 관계 조건자를 포함하는 쿼리는 파티션 메타데이터를 직접 로드할 수 있으므로 실행 속도가 더 빠릅니다. 하나 이상의 파티션 키에 조건자가 없거나 조건자에서 값 범위를 선택하는 쿼리는 피합니다. 이러한 쿼리의 경우 일치하는 값을 찾으려면 모든 파티션 목록을 필터링해야 합니다. 대부분의 테이블에서 이러한 오버헤드가 최소한의 수준이지만, 파티션이 수만 개가 넘는 테이블의 경우 이러한 오버헤드는 심각해질 수 있습니다.

쿼리를 다시 작성하여 파티션을 관계 조건자로 필터링할 수 없는 경우 파티션 프로젝션을 시도할 수 있습니다. 자세한 내용은 [파티션 프로젝션 사용](#performance-tuning-use-partition-projection) 섹션을 참조하세요.

## 파티션 유지 관리에 MSCK REPAIR TABLE 사용 방지
<a name="performance-tuning-avoid-using-msck-repair-table-for-partition-maintenance"></a>

`MSCK REPAIR TABLE`은 실행 시간이 오래 걸릴 수 있으며 새 파티션만 추가하고 오래된 파티션은 제거하지 않으므로 파티션을 효율적으로 관리할 수 있는 방법이 아닙니다([고려 사항 및 제한 사항](msck-repair-table.md#msck-repair-table-considerations) 참조)

파티션은 [AWS Glue Data Catalog API](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-api-catalog.html), [ALTER TABLE ADD PARTITION](alter-table-add-partition.md) 또는 [AWS Glue 크롤러](https://docs.aws.amazon.com/glue/latest/dg/crawler-running.html)를 사용하여 수동으로 관리하는 것이 보다 효율적입니다. 다른 방법으로, 파티션 프로젝션을 사용할 수도 있습니다. 그러면 파티션을 모두 관리할 필요가 없습니다. 자세한 내용은 [Amazon Athena에서 파티션 프로젝션 사용](partition-projection.md) 섹션을 참조하세요.

## 쿼리가 파티셔닝 체계와 호환되는지 확인
<a name="performance-tuning-validate-that-your-queries-are-compatible-with-the-partitioning-scheme"></a>

[`EXPLAIN`](athena-explain-statement.md) 문을 사용하여 쿼리에서 스캔할 파티션을 미리 확인할 수 있습니다. 쿼리 앞에 `EXPLAIN` 키워드를 접두사로 추가하고 각 테이블의 `Fragment 2 [SOURCE]` 출력 하단 근처에서 소스 조각(예:`EXPLAIN`)를 조회합니다. 오른쪽이 파티션 키로 정의된 할당을 조회합니다. 아래 줄에는 쿼리가 실행될 때 스캔할 해당 파티션 키의 모든 값 목록이 포함되어 있습니다.

예를 들어 `dt` 파티션 키가 있는 테이블에 쿼리가 있고 이 쿼리에 `EXPLAIN` 접두사를 추가한다고 가정합니다. 쿼리의 값이 날짜이고 필터로 3일 범위를 선택하는 경우 `EXPLAIN` 출력은 다음과 비슷합니다.

```
dt := dt:string:PARTITION_KEY
    :: [[2023-06-11], [2023-06-12], [2023-06-13]]
```

`EXPLAIN` 출력에서는 플래너가 이 파티션 키에 대해 쿼리와 일치하는 세 개의 값을 찾았음을 보여줍니다. 또한 해당 값도 표시합니다. `EXPLAIN` 사용에 대한 자세한 내용은 [Athena에서 EXPLAIN 및 EXPLAIN ANALYZE 사용](athena-explain-statement.md) 및 [Athena EXPLAIN 문 결과 이해](athena-explain-statement-understanding.md) 섹션을 참조하세요.

## 열 기반 파일 형식 사용
<a name="performance-tuning-use-columnar-file-formats"></a>

Parquet 및 ORC와 같은 열 기반 파일 형식은 분산 분석 워크로드를 위해 설계되었습니다. 이 파일 형식에서는 데이터를 행 대신 열을 기준으로 구성합니다. 데이터를 열 형식으로 구성하면 다음과 같은 이점이 있습니다.
+ 쿼리에 필요한 열만 로드됨
+ 로드해야 하는 전체 데이터 양이 감소함
+ 열 값이 함께 저장되므로 데이터를 효율적으로 압축할 수 있음 
+ 엔진에서 불필요한 데이터를 로드하지 않고 건너뛸 수 있도록 하는 메타데이터가 파일에 포함될 수 있음

파일 메타데이터를 사용하는 방법의 예로, 파일 메타데이터에서 데이터 페이지에 최솟값 및 최댓값에 대한 정보가 포함될 수 있습니다. 쿼리된 값이 메타데이터에 명시된 범위를 벗어나면 페이지를 건너뛸 수 있습니다.

이 메타데이터를 사용하여 성능을 향개선하는 한 가지 방법은 파일 내의 데이터를 정렬하는 것입니다. 예를 들어 `created_at` 항목이 짧은 기간에 포함된 레코드를 찾는 쿼리를 가정합니다. 데이터가 `created_at` 열을 기준으로 정렬된 경우 Athena는 파일 메타데이터의 최솟값과 최댓값을 사용하여 데이터 파일의 불필요한 부분을 건너뛸 수 있습니다.

열 기반 파일 형식을 사용하는 경우 파일 크기가 너무 작지 않아야 합니다. [너무 많은 수의 파일 방지](#performance-tuning-avoid-having-too-many-files)에서 설명한 것처럼 작은 파일이 많은 데이터 세트는 성능 문제를 일으킬 수 있습니다. 열 기반 파일 형식에서 특히 그렇습니다. 크기가 작은 파일의 경우 열 기반 파일 형식에서 오버헤드의 단점이 장점보다 더 큽니다.

Parquet 및 ORC는 내부적으로 행 그룹(Parquet) 및 스트라이프(ORC)로 구성됩니다. 행 그룹의 기본 크기는 128MB이고 스트라이프의 경우 64MB입니다. 열이 많은 경우 더 나은 성능을 위해 행 그룹과 스트라이프 크기를 늘릴 수 있습니다. 행 그룹 또는 스트라이프 크기를 기본값보다 작게 줄이는 것은 권장되지 않습니다.

다른 데이터 형식을 Parquet 또는 ORC로 변환하기 위해 AWS Glue ETL 또는 Athena를 사용할 수 있습니다. 자세한 내용은 [열 기반 형식으로 변환](columnar-storage.md#convert-to-columnar) 섹션을 참조하세요.

## 데이터 압축
<a name="performance-tuning-compress-data"></a>

Athena에서는 다양한 압축 형식을 지원합니다. 압축을 해제하기 전에 스캔한 바이트 수만큼 비용이 청구되므로 압축된 데이터를 쿼리하는 것이 더 빠르고 비용도 저렴합니다.

[gzip](https://www.gnu.org/software/gzip/) 형식은 뛰어난 압축률을 제공하며 다른 여러 도구 및 서비스에서 폭넓게 지원됩니다. [zstd](https://facebook.github.io/zstd/)(Zstandard) 형식은 성능과 압축률 간 균형이 잘 잡힌 최신 압축 형식입니다.

JSON 및 CSV 데이터와 같은 텍스트 파일을 압축할 때는 파일 수와 파일 크기 사이의 균형을 맞춥니다. 대부분의 압축 형식을 사용하려면 처음부터 리더에서 파일을 읽어야 합니다. 즉, 압축된 텍스트 파일은 일반적으로 병렬로 처리할 수 없습니다. 압축되지 않은 큰 파일은 쿼리 처리 중에 병렬 처리 성능을 높이기 위해 종종 작업자 사이에서 분할되기도 하지만, 대부분의 압축 형식에서는 지원되지 않습니다.

[너무 많은 수의 파일 방지](#performance-tuning-avoid-having-too-many-files)에서 설명한 것처럼 파일이 너무 많거나 너무 적지 않은 것이 좋습니다. 파일 수는 쿼리를 처리할 수 있는 작업자 수의 한도이므로 이 규칙은 특히 압축된 파일에 적용됩니다.

Athena에서 압축 사용에 대한 자세한 내용은 [Athena에서 압축 사용](compression-formats.md) 섹션을 참조하세요.

## 카디널리티가 높은 키에서 조회할 때 버킷팅 사용
<a name="performance-tuning-use-bucketing-for-lookups-on-keys-with-high-cardinality"></a>

버킷팅은 열 중 하나의 값을 기준으로 레코드를 별도의 파일로 분산하는 기법입니다. 이렇게 하면 값이 같은 모든 레코드가 같은 파일에 보관됩니다. 버킷팅은 카디널리티가 높은 키가 있고 많은 쿼리에서 해당 키의 특정 값을 조회하는 경우에 유용합니다.

예를 들어 특정 사용자에 대한 레코드 세트를 쿼리한다고 가정합니다. 데이터가 사용자 ID로 버킷팅되는 경우 Athena는 특정 ID에 대한 레코드를 포함하는 파일과 그렇지 않은 파일을 미리 파악합니다. 이를 통해 Athena가 ID를 포함할 수 있는 파일만 읽을 수 있으므로 읽는 데이터의 양이 크게 줄어듭니다. 또한 특정 ID를 찾기 위해 데이터를 검색하는 데 필요한 컴퓨팅 시간도 줄어듭니다.

### 쿼리에서 열의 여러 값을 자주 검색하는 경우 버킷팅 방지
<a name="performance-tuning-disadvantages-of-bucketing"></a>

쿼리에서 데이터가 버킷팅되는 열의 여러 값을 자주 검색하는 경우에는 버킷팅의 효율성이 떨어집니다. 쿼리되는 값이 많을수록 전체 또는 대부분의 파일을 읽어야 할 가능성이 커집니다. 예를 들어 버킷이 3개이고 쿼리에서 세 개의 다른 값을 조회하는 경우 모든 파일을 읽어야 할 수 있습니다. 버킷팅은 쿼리에서 단일 값을 조회할 때 가장 효과적입니다.

자세한 내용은 [분할 및 버킷팅 사용](ctas-partitioning-and-bucketing.md) 섹션을 참조하세요.

## 너무 많은 수의 파일 방지
<a name="performance-tuning-avoid-having-too-many-files"></a>

많은 수의 작은 파일로 구성된 데이터 세트는 전체 쿼리 성능을 저하시킵니다. Athena는 쿼리를 계획할 때 모든 파티션 위치를 나열하므로 시간이 걸립니다. 각 파일을 처리하고 요청하는 데에도 계산 오버헤드가 발생합니다. 따라서 Amazon S3에서 큰 파일 하나를 로드하는 것이 많은 수의 작은 파일에서 동일한 레코드를 로드하는 것보다 빠릅니다.

극단적인 경우에는 Amazon S3 서비스 한도에 도달할 수 있습니다. Amazon S3는 단일 인덱스 파티션에 대해 초당 최대 5,500개의 요청을 지원합니다. 처음에는 버킷을 단일 인덱스 파티션으로 취급하지만 요청 로드가 증가하면 여러 인덱스 파티션으로 분할할 수 있습니다.

Amazon S3는 요청 패턴을 확인하고 키 접두사를 기반으로 분할합니다. 데이터 세트가 수천 개의 파일로 구성된 경우 Athena에서 수신되는 요청이 요청 할당량을 초과할 수 있습니다. 파일 수가 적더라도 동일한 데이터 세트에 대해 여러 개의 동시 쿼리를 수행하면 할당량을 초과할 수 있습니다. 동일한 파일에 액세스하는 다른 애플리케이션이 총 요청 수에 영향을 미칠 수도 있습니다.

요청 속도(`limit`)를 초과하면 Amazon S3는 다음 오류를 반환합니다. 이 오류는 Athena에서 쿼리 상태 정보에 포함됩니다.

 SlowDown: Please reduce your request rate 

문제를 해결하려면 먼저 오류가 단일 쿼리에서 발생했는지, 아니면 동일한 파일을 읽는 여러 쿼리에서 발생했는지 확인합니다. 후자인 경우 쿼리가 동시에 실행되지 않도록 쿼리 실행을 조정합니다. 이를 위해 애플리케이션에 대기열 메커니즘을 추가하거나 재시도를 추가합니다.

단일 쿼리를 실행할 때 오류가 발생하는 경우 데이터 파일을 결합하거나 읽는 파일 수를 줄이도록 쿼리를 수정합니다. 작은 파일을 결합하기에 가장 좋은 시점은 파일을 쓰기 전입니다. 이를 위해 다음 기법을 고려합니다.
+ 더 큰 파일을 쓰도록 파일을 쓰는 프로세스를 변경합니다. 예를 들어 레코드를 쓰기 전에 더 오래 레코드를 버퍼링할 수 있습니다.
+ Amazon S3의 한 위치에 파일을 배치하고 Glue ETL과 같은 도구를 사용하여 파일을 더 큰 파일로 결합합니다. 그런 다음 큰 파일을 테이블이 가리키는 위치로 이동합니다. 자세한 내용은 *AWS Glue 개발자 안내서*의 [Reading input files in larger groups](https://docs.aws.amazon.com/glue/latest/dg/grouping-input-files.html) 및 *AWS re:Post 지식 센터*의 [더 큰 파일을 출력하도록 AWS Glue ETL 작업을 구성하려면 어떻게 해야 합니까?](https://repost.aws/knowledge-center/glue-job-output-large-files)를 참조하세요.
+ 파티션 키 수를 줄입니다. 파티션 키가 너무 많으면 각 파티션에 레코드 수가 적어 작은 파일 수가 너무 많아질 수 있습니다. 생성할 파티션 결정에 대한 자세한 내용은 [쿼리를 지원하는 파티션 키를 선택합니다.](#performance-tuning-pick-partition-keys-that-will-support-your-queries) 섹션을 참조하세요.

## 파티션 이외의 추가 스토리지 계층 구조 방지
<a name="performance-tuning-avoid-additional-storage-hierarchies-beyond-the-partition"></a>

쿼리 계획 오버헤드를 방지하려면 각 파티션 위치에 파일을 플랫 구조로 저장합니다. 추가 디렉터리 계층 구조는 사용하지 않습니다.

Athena는 쿼리를 계획할 때 쿼리와 일치하는 모든 파티션의 모든 파일을 나열합니다. Amazon S3에 디렉터리 자체는 없지만, `/` 슬래시를 디렉터리 구분 기호로 해석하는 것이 규칙입니다. Athena는 파티션 위치를 나열할 때 찾은 모든 디렉터리를 반복적으로 나열합니다. 파티션 내 파일을 계층 구조로 구성하면 여러 차례 나열이 수행됩니다.

모든 파일이 파티션 위치에 바로 있으면 대부분의 경우 한 번의 나열 작업만 수행하면 됩니다. 그러나 Amazon S3는 나열 작업당 1,000개의 객체만 반환하므로 파티션에 1,000개가 넘는 파일이 있으면 순차 나열 작업이 여러 차례 필요합니다. 파티션에 1,000개가 넘는 파일이 있으면 더 심각한 다른 성능 문제가 발생할 수도 있습니다. 자세한 내용은 [너무 많은 수의 파일 방지](#performance-tuning-avoid-having-too-many-files) 섹션을 참조하세요.

## 필요한 경우에만 SymlinkTextInputFormat 사용
<a name="performance-tuning-use-symlinktextinputformat-only-when-necessary"></a>

[https://athena.guide/articles/stitching-tables-with-symlinktextinputformat](https://athena.guide/articles/stitching-tables-with-symlinktextinputformat) 기법을 사용하면 테이블의 파일이 파티션으로 깔끔하게 구성되지 않은 상황을 해결할 수 있습니다. 예를 들어 모든 파일에서 접두사가 같거나 스키마가 다른 파일이 같은 위치에 있는 경우 symlink가 유용할 수 있습니다.

하지만 symlink를 사용하면 쿼리 실행이 더 간접적으로 이루어집니다. 이렇게 간접적으로 이루어진 쿼리 실행은 전체 성능에 영향을 미칩니다. symlink 파일을 읽고 symlink 파일이 정의한 위치를 나열해야 합니다. 이로 인해 일반적인 Hive 테이블에서는 필요하지 않은 여러 번의 왕복 작업이 Amazon S3에 추가됩니다. 결론적으로, 파일 재구성과 같은 더 나은 옵션을 사용할 수 없는 경우에만 `SymlinkTextInputFormat`을 사용해야 합니다.

# 열 기반 스토리지 형식 사용
<a name="columnar-storage"></a>

[Apache Parquet](https://parquet.apache.org) 및 [ORC](https://orc.apache.org/)는 빠른 데이터 검색에 최적화되어 있고, AWS 분석 애플리케이션에서 사용되는 열 기반 스토리지 형식입니다.

열 기반 스토리지 형식에는 Athena에서 사용하는 데 적합하게 만드는 다음과 같은 특징이 있습니다.
+ *열 기준 압축, 열 데이터 유형에 대해 선택한 압축 알고리즘 사용*: Amazon S3에서 스토리지 공간을 절약하고 쿼리 처리 중 디스크 공간 및 I/O를 줄입니다.
+ Parquet 및 ORC의 *조건자 푸시다운*: Athena에서 필요한 블록만 가져오도록 쿼리할 수 있어 쿼리 성능을 높입니다. Athena 쿼리가 데이터에서 특정 열 값을 얻으면 데이터 블록 조건자의 통계(예: 최대값/최소값)를 사용해 블록을 읽거나 건너뛸지 결정합니다.
+ Parquet 및 ORC의 *데이터 분할*: Athena에서 쿼리 처리 중 데이터 읽기를 여러 리더에게 분할해 병렬 처리를 늘립니다.

기존 원시 데이터를 다른 스토리지 형식에서 Parquet 또는 ORC로 변환하려면 Athena에서 [CREATE TABLE AS SELECT (CTAS)](ctas.md) 쿼리를 실행하고 데이터 스토리지 형식을 Parquet 또는 ORC로 지정하거나 AWS Glue 크롤러를 사용합니다.

## Parquet 및 ORC 중에서 선택
<a name="columnar-storage-choosing"></a>

Optimized Row Columnar(ORC) 및 Parquet 중에서의 선택은 특정 사용 요구 사항에 따라 다릅니다.

Apache Parquet은 효율적인 데이터 압축 및 인코딩 체계를 제공하며 복잡한 쿼리를 실행하고 대량의 데이터를 처리하는 데 적합합니다. Parquet은 [Apache Arrow](https://arrow.apache.org/)와 함께 사용하도록 최적화되어 있으므로 Arrow 관련 도구를 사용하는 경우 더 유용합니다.

ORC는 Hive 데이터를 저장하는 효율적인 방법을 제공합니다. ORC 파일은 종종 Parquet 파일보다 크기가 작으며 ORC 인덱스를 사용하면 쿼리 속도를 높일 수 있습니다. 또한 ORC는 구조체, 맵, 목록과 같은 복잡한 유형을 지원합니다.

Parquet 및 ORC 중에서 선택할 때는 다음을 고려합니다.

**쿼리 성능** - Parquet은 더 광범위한 쿼리 유형을 지원하므로 복잡한 쿼리를 수행하려는 경우 Parquet이 더 적합합니다.

**복잡한 데이터 유형** - 복잡한 데이터 유형을 사용하는 경우 다양한 복잡한 데이터 유형을 지원하는 ORC가 더 적합합니다.

**파일 크기** - 디스크 공간이 우려되는 경우 일반적으로 ORC에서는 파일 크기가 더 작으므로 스토리지 비용을 절감할 수 있습니다.

**압축** - Parquet 및 ORC 모두 뛰어난 압축률을 제공하지만 최적의 형식은 특정 사용 사례에 따라 달라질 수 있습니다.

**진화** - Parquet과 ORC 모두 스키마 진화를 지원하므로 시간이 지남에 따라 열을 추가, 제거 또는 수정할 수 있습니다.

Parquet 및 ORC 모두 빅 데이터 애플리케이션에 적합하지만 선택하기 전에 시나리오의 요구 사항을 고려합니다. 데이터 및 쿼리에 대한 벤치마크를 수행하여 사용 사례에 더 적합한 형식을 확인하는 것이 좋습니다.

## 열 기반 형식으로 변환
<a name="convert-to-columnar"></a>

JSON 또는 CSV와 같은 소스 데이터를 열 형식으로 쉽게 변환할 수 있는 옵션을 통해 [CREATE TABLE AS](ctas.md) 쿼리를 사용하거나 AWS Glue의 작업을 실행할 수 있습니다.
+ `CREATE TABLE AS`(CTAS) 쿼리를 통해 한 번에 데이터를 Parquet 또는 ORC로 변환할 수 있습니다. 예는 [CTAS 쿼리 예제](ctas-examples.md) 페이지의 [예제: 쿼리 결과를 다른 형식으로 쓰기](https://docs.aws.amazon.com/athena/latest/ug/ctas-examples.html#ctas-example-format)를 참조하세요.
+ ETL에 Athena를 사용하여 데이터를 CSV에서 Parquet으로 변환하는 방법에 대한 자세한 내용은 [ETL 및 데이터 분석에 CTAS 및 INSERT INTO 사용](ctas-insert-into-etl.md) 섹션을 참조하세요.
+ AWS Glue 작업을 실행하여 CSV 데이터를 Parquet으로 변환하는 방법에 대한 자세한 내용은 AWS 빅 데이터 블로그 게시물 [Amazon S3 및 AWS Glue를 이용한 데이터 레이크 구축하기](https://aws.amazon.com/blogs/big-data/build-a-data-lake-foundation-with-aws-glue-and-amazon-s3/)의 'CSV에서 Parquet 형식으로 데이터 변환' 섹션을 참조하세요. AWS Glue에서는 동일한 기술을 사용하여 CSV 데이터를 ORC로 변환하거나 JSON 데이터를 Parquet 또는 ORC로 변환할 수 있습니다.

# 분할 및 버킷팅 사용
<a name="ctas-partitioning-and-bucketing"></a>

파티셔닝과 버킷팅은 Athena에서 쿼리를 실행할 때 스캔해야 하는 데이터의 양을 줄이는 두 가지 방법입니다. 파티셔닝 및 버킷팅은 상호 보완적이며 함께 사용할 수 있습니다. 스캔하는 데이터의 양을 줄이면 성능이 향상되고 비용이 절감됩니다. Athena 쿼리 성능에 대한 일반적인 지침은 [Top 10 performance tuning tips for Amazon Athena](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/)를 참조하세요.

**Topics**
+ [파티셔닝이란 무엇인가요?](ctas-partitioning-and-bucketing-what-is-partitioning.md)
+ [버킷팅이란 무엇인가요?](ctas-partitioning-and-bucketing-what-is-bucketing.md)
+ [추가 리소스](ctas-partitioning-and-bucketing-additional-resources.md)

# 파티셔닝이란 무엇인가요?
<a name="ctas-partitioning-and-bucketing-what-is-partitioning"></a>

파티셔닝이란 데이터의 특정 속성을 기반으로 Amazon S3의 디렉터리(또는 '접두사')로 데이터를 구성하는 작업을 의미합니다. 이러한 속성을 파티션 키라고 합니다. 일반적인 파티션 키는 날짜 또는 기타 시간 단위(예: 연도 또는 월)입니다. 하지만 데이터 세트는 둘 이상의 키로 파티셔닝할 수 있습니다. 예를 들어 제품 판매에 대한 데이터를 날짜, 제품 카테고리 및 마켓에 따라 파티셔닝할 수 있습니다.

## 파티셔닝 방법 결정
<a name="ctas-partitioning-and-bucketing-deciding-how-to-partition"></a>

쿼리에 항상 또는 자주 사용되고 카디널리티가 낮은 속성이 파티션 키로 사용하기에 적합합니다. 파티셔닝이 너무 많은 경우와 너무 적은 경우 사이에는 상충 관계가 있습니다. 파티션이 너무 많으면 파일 수가 증가하여 오버헤드가 발생합니다. 파티션 자체를 필터링하는 데 약간의 오버헤드도 발생합니다. 파티션이 너무 적으면 쿼리에서 더 많은 데이터를 스캔해야 하기도 합니다.

## 분할된 테이블 생성
<a name="ctas-partitioning-and-bucketing-creating-a-partitioned-table"></a>

데이터 세트가 파티셔닝되면 Athena에서 파티셔닝된 테이블을 생성할 수 있습니다. 파티셔닝된 테이블은 파티션 키가 있는 테이블입니다. `CREATE TABLE`을 사용하는 경우 테이블에 파티션을 추가합니다. `CREATE TABLE AS`을 사용하는 경우 Amazon S3에 생성된 파티션이 테이블에 자동으로 추가됩니다.

`CREATE TABLE` 문에서 `PARTITIONED BY (column_name data_type)` 절에 파티션 키를 지정합니다. `CREATE TABLE AS`에서는 `WITH (partitioned_by = ARRAY['partition_key'])` 절에 파티션 키를 지정하거나 Iceberg 테이블의 경우 `WITH (partitioning = ARRAY['partition_key'])` 절에 지정합니다. 성능을 고려하여 파티션 키는 항상 `STRING` 유형이어야 합니다. 자세한 내용은 [파티션 키의 데이터 형식으로 문자열 사용](data-types-timestamps.md#data-types-timestamps-partition-key-types) 섹션을 참조하세요.

추가적인 `CREATE TABLE` 및 `CREATE TABLE AS` 구문 세부 정보는 [CREATE TABLE](create-table.md) 및 [CTAS 테이블 속성](create-table-as.md#ctas-table-properties) 섹션을 참조하세요.

## 분할된 테이블 쿼리
<a name="ctas-partitioning-and-bucketing-querying-partitioned-tables"></a>

파티셔닝된 테이블을 쿼리하면 Athena는 쿼리에서 조건자를 사용하여 파티션 목록을 필터링합니다. 그런 다음 일치하는 파티션의 위치를 사용하여 찾은 파일을 처리합니다. Athena는 쿼리 조건자와 일치하지 않는 파티션의 데이터를 읽지 않음으로써 스캔하는 데이터의 양을 효율적으로 줄일 수 있습니다.

### 예제
<a name="ctas-partitioning-and-bucketing-partitioned-table-example-queries"></a>

`sales_date` 및 `product_category`를 기준으로 파티셔닝된 테이블이 있고 특정 카테고리에서 1주일 간의 총 수익을 알고자 합니다. Athena가 다음 예제와 같이 최소의 데이터만 스캔하도록 하기 위해 `sales_date` 및 `product_category` 열에 조건자를 포함합니다.

```
SELECT SUM(amount) AS total_revenue 
FROM sales 
WHERE sales_date BETWEEN '2023-02-27' AND '2023-03-05' 
AND product_category = 'Toys'
```

데이터 세트가 날짜를 기준으로 파티셔닝되었지만 정밀한 타임스탬프도 있다고 가정합니다.

Iceberg 테이블을 사용하면 열과 관계를 설정하도록 파티션 키를 선언할 수 있지만, Hive 테이블을 사용하면 쿼리 엔진이 열과 파티션 키 간 관계를 인식하지 못합니다. 따라서 쿼리에서 필요한 것보다 많은 데이터를 스캔하지 않도록 하려면 쿼리에서 열과 파티션 키 모두에 조건자를 포함해야 합니다.

예를 들어 이전 예제의 `sales` 테이블에도 해당 `TIMESTAMP` 데이터 형식의 `sold_at` 열이 있다고 가정합니다. 특정 시간 범위의 매출만 원하는 경우 다음과 같이 쿼리를 작성합니다.

```
SELECT SUM(amount) AS total_revenue 
FROM sales 
WHERE sales_date = '2023-02-28' 
AND sold_at BETWEEN TIMESTAMP '2023-02-28 10:00:00' AND TIMESTAMP '2023-02-28 12:00:00' 
AND product_category = 'Toys'
```

Hive 테이블과 Iceberg 테이블 쿼리 사이의 이러한 차이에 대한 자세한 내용은 [시간을 기준으로 파티셔닝된 타임스탬프 필드에 대한 쿼리를 작성하는 방법](data-types-timestamps.md#data-types-timestamps-how-to-write-queries-for-timestamp-fields-that-are-also-time-partitioned) 섹션을 참조하세요.

# 버킷팅이란 무엇인가요?
<a name="ctas-partitioning-and-bucketing-what-is-bucketing"></a>

버킷팅은 데이터 세트의 레코드를 버킷이라는 카테고리로 구성하는 방법입니다.

버킷 및 버킷팅의 의미는 서로 다르며, Amazon S3 버킷과도 혼동해서는 안 됩니다. 데이터 버킷팅에서 속성 값이 동일한 레코드는 동일한 버킷으로 이동합니다. 레코드는 각 버킷이 대략 같은 양의 데이터를 보유하도록 버킷 사이에서 최대한 균등하게 분산됩니다.

실제로 버킷은 파일이고 해시 함수에서 레코드를 배치할 버킷을 결정합니다. 버킷팅된 데이터 세트에는 파티션 1개에 버킷당 하나 이상의 파일이 있습니다. 파일이 속한 버킷은 파일 이름에서 인코딩됩니다.

## 버킷팅의 장점
<a name="ctas-partitioning-and-bucketing-bucketing-benefits"></a>

버킷팅은 데이터 세트가 특정 속성을 기준으로 버킷팅되고 해당 속성에 특정 값이 있는 레코드를 검색하려는 경우에 유용합니다. 데이터가 버킷팅되어 있기 때문에 Athena는 값을 사용하여 찾을 파일을 결정할 수 있습니다. 예를 들어 데이터 세트가 `customer_id`를 기준으로 버킷팅되었고 특정 고객에 대한 모든 레코드를 찾고 싶다고 가정합니다. Athena는 이러한 레코드를 포함하는 버킷을 확인하고 해당 버킷의 파일만 읽습니다.

카디널리티가 높고(즉, 개별 값이 많음) 열이 균등하게 분산되었으며 특정 값을 자주 쿼리하는 열이 있을 때 버킷팅에 적합합니다.

**참고**  
Athena는 버킷팅된 테이블에 새 레코드를 추가할 때 `INSERT INTO` 사용을 지원하지 않습니다.

## 버킷팅된 열에 대한 필터링에 지원되는 데이터 형식
<a name="ctas-partitioning-and-bucketing-data-types-supported-for-filtering-on-bucketed-columns"></a>

특정 데이터 형식으로 버킷팅된 열에 필터를 추가할 수 있습니다. Athena는 다음과 같은 데이터 형식의 버킷팅된 열에서 필터링을 지원합니다.
+ BOOLEAN
+ BYTE
+ DATE
+ DOUBLE
+ FLOAT
+ INT
+ LONG
+ SHORT
+ STRING
+ VARCHAR

## Hive 및 Spark 지원
<a name="ctas-partitioning-and-bucketing-hive-and-spark-support"></a>

Athena 엔진 버전 2는 Hive 버킷 알고리즘을 사용하여 버킷팅된 데이터 세트를 지원하며 Athena 엔진 버전 3은 Apache Spark 버킷팅 알고리즘도 지원합니다. Hive 버킷팅이 기본값입니다. Spark 알고리즘을 사용하여 데이터 세트를 버킷팅하는 경우 `TBLPROPERTIES` 절을 사용하여 `bucketing_format` 속성 값을 `spark`로 설정합니다.

**참고**  
Athena는 `CREATE TABLE AS SELECT`([CTAS](ctas.md)) 쿼리당 파티션을 100개로 제한합니다. 마찬가지로, [INSERT INTO](insert-into.md) 문을 통해 대상 테이블에 최대 100개의 파티션만 추가할 수 있습니다.  
이 제한을 초과하면 “HIVE\$1TOO\$1MANY\$1OPEN\$1파티션: 파티션/버킷에 대해 열린 작성자 100개를 초과했습니다.”라는 오류 메시지가 표시될 수 있습니다. 이러한 제한은 CTAS 문(최대 100개의 파티션 생성) 및 일련의 `INSERT INTO` 문(각각 최대 100개의 파티션 삽입)을 사용하여 해결할 수 있습니다. 자세한 내용은 [CTAS 및 INSERT INTO를 사용하여 100개 파티션 한도 문제 해결](ctas-insert-into.md) 섹션을 참조하세요.

## CREATE TABLE 버킷팅 예제
<a name="ctas-partitioning-and-bucketing-bucketing-create-table-example"></a>

기존의 버킷팅된 데이터 세트에 대한 테이블을 생성하려면 `CLUSTERED BY (column)` 절 및 `INTO N BUCKETS`절을 차례로 사용합니다. `INTO N BUCKETS` 절은 데이터가 버킷팅되는 버킷 수를 지정합니다.

다음 `CREATE TABLE` 예제에서는 Spark 알고리즘을 사용하여 `customer_id`를 기준으로 `sales` 데이터 세트를 8개의 버킷으로 버킷팅합니다. `CREATE TABLE` 문에서는 `CLUSTERED BY` 및 `TBLPROPERTIES` 절을 사용하여 속성을 적절하게 설정합니다.

```
CREATE EXTERNAL TABLE sales (...) 
... 
CLUSTERED BY (`customer_id`) INTO 8 BUCKETS 
... 
TBLPROPERTIES ( 
  'bucketing_format' = 'spark' 
)
```

## CREATE TABLE AS(CTAS) 버킷팅 예제
<a name="ctas-partitioning-and-bucketing-bucketing-create-table-as-example"></a>

`CREATE TABLE AS`를 사용하여 버킷팅을 지정하려면 다음 예제와 같이 `bucketed_by` 및 `bucket_count` 파라미터를 사용합니다.

```
CREATE TABLE sales 
WITH ( 
  ... 
  bucketed_by = ARRAY['customer_id'], 
  bucket_count = 8 
) 
AS SELECT ...
```

## 버킷팅 쿼리 예제
<a name="ctas-partitioning-and-bucketing-bucketing-query-example"></a>

다음 쿼리 예제는 특정 고객이 1주일 동안 구매한 제품의 이름을 찾습니다.

```
SELECT DISTINCT product_name 
FROM sales 
WHERE sales_date BETWEEN '2023-02-27' AND '2023-03-05' 
AND customer_id = 'c123'
```

이 테이블이 `sales_date`를 기준으로 파티셔닝되고 `customer_id`를 기준으로 버키팅된 경우 Athena는 고객 레코드가 들어 있는 버킷을 계산할 수 있습니다. Athena는 파티션당 최대 하나의 파일 정도만 읽습니다.

# 추가 리소스
<a name="ctas-partitioning-and-bucketing-additional-resources"></a>
+ 버킷팅 및 파티셔닝된 테이블 모두를 생성하는 `CREATE TABLE AS` 예제는 [예제: 버킷팅 및 파티셔닝된 테이블 생성](https://docs.aws.amazon.com/athena/latest/ug/ctas-examples.html#ctas-example-bucketed)을 참조하세요.
+ Athena CTAS 명령문, Apache Spark용 AWS Glue 및 Apache Iceberg 테이블에 대한 버킷팅 등 AWS 데이터 레이크에 버킷팅을 구현하는 방법에 자세한 내용은 AWS 빅 데이터 블로그 게시물 [Optimize data layout by bucketing with Amazon Athena and AWS Glue to accelerate downstream queries](https://aws.amazon.com/blogs/big-data/optimize-data-layout-by-bucketing-with-amazon-athena-and-aws-glue-to-accelerate-downstream-queries/)를 참조하세요.

# 데이터 파티셔닝
<a name="partitions"></a>

데이터를 분할하면 각 쿼리가 스캔하는 데이터의 양을 제한하여 성능을 향상시키고 비용을 절감할 수 있습니다. 어떤 키를 기준으로도 데이터를 분할할 수 있습니다. 일반적으로 시간을 기준으로 데이터가 분할되어, 다중 레벨 파티셔닝 체계가 형성되는 경우가 많습니다. 예를 들어, 매시간 데이터를 수집하는 고객은 연, 월, 일, 시를 기준으로 분할할 수 있습니다. 다양한 소스로부터 데이터를 수집하되 하루에 한 번만 로드하는 고객의 경우 데이터 원본 식별자 및 날짜별로 분할할 수 있습니다.

Athena는 Apache Hive 스타일 파티션을 사용할 수 있습니다. 이 파티션의 데이터 경로에 등호로 연결된 키 값 페어가 포함되어 있습니다(예: `country=us/...` 또는 `year=2021/month=01/day=26/...`). 따라서 경로에는 파티션 키의 이름과 각 경로가 나타내는 값이 모두 포함됩니다. 파티션을 나눈 테이블에 새 Hive 파티션을 로드하려면 [MSCK REPAIR TABLE](msck-repair-table.md) 명령을 사용할 수 있으며 이 명령은 Hive 스타일 파티션에서만 작동합니다.

Athena는 비 Hive 스타일 파티션 체계를 사용할 수도 있습니다. 예를 들어 CloudTrail 로그 및 Firehose 전송 스트림은 `data/2021/01/26/us/6fc7845e.json`와 같은 날짜 부분에 대해 별도의 경로 구성 요소를 사용합니다. Hive와 호환되지 않는 데이터의 경우 [ALTER TABLE ADD PARTITION](alter-table-add-partition.md)을(를) 사용하여 파티션을 수동으로 추가합니다.

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

파티셔닝을 사용할 때는 다음 사항에 유의하세요.
+ `WHERE` 절에서 분할된 테이블을 쿼리하고 파티션을 지정하면 Athena는 해당 파티션의 데이터만 검색합니다.
+ 객체가 많은 Amazon S3 버킷에 대해 쿼리를 실행하는데 데이터가 분할되지 않은 경우, 그러한 쿼리는 Amazon S3의 `GET` 요청 빈도 제한에 영향을 주고 Amazon S3 예외를 발생시킬 수 있습니다. 오류를 방지하려면 데이터를 분할하세요. 또한 Amazon S3 요청 빈도를 조정합니다. 자세한 내용은 [모범 사례 설계 패턴: Amazon S3 성능 최적화](https://docs.aws.amazon.com/AmazonS3/latest/userguide/request-rate-perf-considerations.html)를 참조하세요.
+ Athena에 사용될 파티션 위치는 `s3` 프로토콜(예: `s3://amzn-s3-demo-bucket/folder/`)을 사용해야 합니다. Athena에서, 다른 프로토콜(예: `s3a://amzn-s3-demo-bucket/folder/`)을 사용하는 위치는 포함 테이블에서 `MSCK REPAIR TABLE` 쿼리를 실행할 때 쿼리 실패를 초래하게 됩니다.
+ Amazon S3 경로가 camel 표기 대신 소문자인지 확인합니다(예: `userId` 대신 `userid`). S3 경로가 camel 표기인 경우 `MSCK REPAIR TABLE`은 AWS Glue Data Catalog에 파티션을 추가하지 않습니다. 자세한 내용은 [MSCK REPAIR TABLE](msck-repair-table.md) 섹션을 참조하세요.
+ `MSCK REPAIR TABLE`은 일치하는 파티션 스키마를 찾기 위해 폴더와 하위 폴더를 모두 스캔하기 때문에 별도의 폴더 계층 구조에 있는 별도의 테이블에 데이터를 보관해야 합니다. 예를 들어 테이블 1의 데이터를 `s3://amzn-s3-demo-bucket1`에 두고 테이블 2에 대한 데이터을 `s3://amzn-s3-demo-bucket1/table-2-data`에 두었다고 가정합시다. 두 테이블이 모두 문자열로 분할된 경우 `MSCK REPAIR TABLE`은 테이블 2의 파티션을 테이블 1에 추가합니다. 이를 방지하려면 대신에 `s3://amzn-s3-demo-bucket1` 및 `s3://amzn-s3-demo-bucket2`와 같은 별도의 폴더 구조를 사용하세요. 이 동작은 Amazon EMR과 Apache Hive에서도 동일합니다.
+ Athena와 함께 AWS Glue Data Catalog를 사용하는 경우 계정 및 테이블당 파티션의 서비스 할당량은 [AWS Glue 엔드포인트 및 할당량](https://docs.aws.amazon.com/general/latest/gr/glue.html)을 참조하세요.
  + Athena는 1천만 개의 파티션이 있는 AWS Glue 테이블에 대한 쿼리를 지원하지만, 단일 스캔으로 1백만 개 이상의 파티션을 읽을 수는 없습니다. 이러한 시나리오에서는 파티션 인덱싱이 유용할 수 있습니다. 자세한 내용을 알아보려면 AWS Big Data Blog(빅 데이터 블로그) 문서인 [Improve Amazon Athena query performance using AWS Glue Data Catalog partition indexes](https://aws.amazon.com/blogs/big-data/improve-amazon-athena-query-performance-using-aws-glue-data-catalog-partition-indexes/)(파티션 인덱스를 사용하여 Amazon Athena 쿼리 성능 향상)를 참조하세요.
+ AWS Glue Data Catalog를 사용하는 경우 파티션 할당량 증가를 요청하려면 [AWS Glue의 Service Quotas 콘솔](https://console.aws.amazon.com/servicequotas/home?region=us-east-1#!/services/glue/quotas)을 방문하세요.

## 분할된 데이터로 테이블 생성 및 로드
<a name="partitions-creating-loading"></a>

파티션을 사용하는 테이블을 생성하려면 [CREATE TABLE](create-table.md) 문에 `PARTITIONED BY` 절을 사용합니다. `PARTITIONED BY` 절은 다음 예와 같이 데이터를 분할하는 키를 정의합니다. `LOCATION` 절은 분할된 데이터의 루트 위치를 지정합니다.

```
CREATE EXTERNAL TABLE users (
first string,
last string,
username string
)
PARTITIONED BY (id string)
STORED AS parquet
LOCATION 's3://amzn-s3-demo-bucket'
```

테이블을 생성한 후 쿼리를 위해 파티션에 데이터를 로드합니다. Hive 스타일 파티션의 경우, [MSCK REPAIR TABLE](msck-repair-table.md)을(를) 실행합니다. Hive 스타일이 아닌 파티션의 경우, [ALTER TABLE ADD PARTITION](alter-table-add-partition.md)을(를) 사용하여 파티션을 수동으로 추가합니다.

## 쿼리를 위해 Hive 스타일 및 비 Hive 스타일 데이터 준비
<a name="partitions-preparing-data"></a>

다음 섹션에서는 Athena에서 쿼리하기 위해 Hive 스타일 및 비 Hive 스타일 데이터를 준비하는 방법을 보여줍니다.

### 시나리오 1: Hive 형식으로 Amazon S3에 저장된 데이터
<a name="scenario-1-data-already-partitioned-and-stored-on-s3-in-hive-format"></a>

이 시나리오에서는 Amazon S3에 있는 별도의 폴더에 파티션이 저장됩니다. 예를 들어 다음은 지정된 접두사 아래에 S3 객체를 나열하는 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/ls.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/ls.html) 명령으로 출력된 샘플 광고 노출에 대한 부분 목록입니다.

```
aws s3 ls s3://elasticmapreduce/samples/hive-ads/tables/impressions/

    PRE dt=2009-04-12-13-00/
    PRE dt=2009-04-12-13-05/
    PRE dt=2009-04-12-13-10/
    PRE dt=2009-04-12-13-15/
    PRE dt=2009-04-12-13-20/
    PRE dt=2009-04-12-14-00/
    PRE dt=2009-04-12-14-05/
    PRE dt=2009-04-12-14-10/
    PRE dt=2009-04-12-14-15/
    PRE dt=2009-04-12-14-20/
    PRE dt=2009-04-12-15-00/
    PRE dt=2009-04-12-15-05/
```

여기서 로그는 날짜, 시간 및 분 단위로 설정된 열 이름(dt)으로 저장됩니다. 분할된 열의 상위 폴더 위치, 스키마 및 이름을 DDL에 포함하면 Athena가 해당 하위 폴더의 데이터를 쿼리할 수 있습니다.

#### 테이블 생성
<a name="creating-a-table"></a>

이 데이터로 테이블을 생성하려면 다음 Athena DDL 문과 같이 'dt'를 따라 파티션을 생성합니다.

```
CREATE EXTERNAL TABLE impressions (
    requestBeginTime string,
    adId string,
    impressionId string,
    referrer string,
    userAgent string,
    userCookie string,
    ip string,
    number string,
    processId string,
    browserCookie string,
    requestEndTime string,
    timers struct<modelLookup:string, requestTime:string>,
    threadId string,
    hostname string,
    sessionId string)
PARTITIONED BY (dt string)
ROW FORMAT  serde 'org.apache.hive.hcatalog.data.JsonSerDe'
LOCATION 's3://elasticmapreduce/samples/hive-ads/tables/impressions/' ;
```

이 테이블은 Hive의 기본 JSON serializer-deserializer를 사용하여 Amazon S3에 저장된 JSON 데이터를 읽습니다. 지원되는 형식에 대한 자세한 내용은 [데이터에 적합한 SerDe 선택](supported-serdes.md) 단원을 참조하세요.

#### MSCK REPAIR TABLE 실행
<a name="run-msck-repair-table"></a>

`CREATE TABLE` 쿼리 실행 후 Athena 쿼리 편집기에서 `MSCK REPAIR TABLE` 명령을 실행하여 다음 예와 같이 파티션을 로드합니다.

```
MSCK REPAIR TABLE impressions
```

이 명령을 실행하면 데이터를 쿼리할 준비가 됩니다.

#### 데이터 쿼리
<a name="query-the-data"></a>

파티션 열을 사용하여 노출 테이블의 데이터를 쿼리합니다. 다음은 그 예입니다.

```
SELECT dt,impressionid FROM impressions WHERE dt<'2009-04-12-14-00' and dt>='2009-04-12-13-00' ORDER BY dt DESC LIMIT 100
```

이 쿼리는 다음과 비슷한 결과를 표시합니다.

```
2009-04-12-13-20    ap3HcVKAWfXtgIPu6WpuUfAfL0DQEc
2009-04-12-13-20    17uchtodoS9kdeQP1x0XThKl5IuRsV
2009-04-12-13-20    JOUf1SCtRwviGw8sVcghqE5h0nkgtp
2009-04-12-13-20    NQ2XP0J0dvVbCXJ0pb4XvqJ5A4QxxH
2009-04-12-13-20    fFAItiBMsgqro9kRdIwbeX60SROaxr
2009-04-12-13-20    V4og4R9W6G3QjHHwF7gI1cSqig5D1G
2009-04-12-13-20    hPEPtBwk45msmwWTxPVVo1kVu4v11b
2009-04-12-13-20    v0SkfxegheD90gp31UCr6FplnKpx6i
2009-04-12-13-20    1iD9odVgOIi4QWkwHMcOhmwTkWDKfj
2009-04-12-13-20    b31tJiIA25CK8eDHQrHnbcknfSndUk
```

### 시나리오 2: 데이터가 Hive 형식으로 분할되지 않음
<a name="scenario-2-data-is-not-partitioned"></a>

다음 예에서 `aws s3 ls` 명령은 Amazon S3에 저장된 [ELB](elasticloadbalancer-classic-logs.md) 로그를 보여줍니다. 데이터 레이아웃이 `key=value` 페어를 사용하지 않으므로 Hive 형식이 아니라는 점에 유의하세요. (`aws s3 ls` 명령에 대한 `--recursive` 옵션은 지정된 디렉터리 또는 접두사 아래의 모든 파일 또는 객체를 나열하도록 지정합니다.)

```
aws s3 ls s3://athena-examples-myregion/elb/plaintext/ --recursive

2016-11-23 17:54:46   11789573 elb/plaintext/2015/01/01/part-r-00000-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:46    8776899 elb/plaintext/2015/01/01/part-r-00001-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:46    9309800 elb/plaintext/2015/01/01/part-r-00002-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47    9412570 elb/plaintext/2015/01/01/part-r-00003-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47   10725938 elb/plaintext/2015/01/01/part-r-00004-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:46    9439710 elb/plaintext/2015/01/01/part-r-00005-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47          0 elb/plaintext/2015/01/01_$folder$
2016-11-23 17:54:47    9012723 elb/plaintext/2015/01/02/part-r-00006-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47    7571816 elb/plaintext/2015/01/02/part-r-00007-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47    9673393 elb/plaintext/2015/01/02/part-r-00008-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48   11979218 elb/plaintext/2015/01/02/part-r-00009-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48    9546833 elb/plaintext/2015/01/02/part-r-00010-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48   10960865 elb/plaintext/2015/01/02/part-r-00011-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48          0 elb/plaintext/2015/01/02_$folder$
2016-11-23 17:54:48   11360522 elb/plaintext/2015/01/03/part-r-00012-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48   11211291 elb/plaintext/2015/01/03/part-r-00013-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48    8633768 elb/plaintext/2015/01/03/part-r-00014-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:49   11891626 elb/plaintext/2015/01/03/part-r-00015-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:49    9173813 elb/plaintext/2015/01/03/part-r-00016-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:49   11899582 elb/plaintext/2015/01/03/part-r-00017-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:49          0 elb/plaintext/2015/01/03_$folder$
2016-11-23 17:54:50    8612843 elb/plaintext/2015/01/04/part-r-00018-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:50   10731284 elb/plaintext/2015/01/04/part-r-00019-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:50    9984735 elb/plaintext/2015/01/04/part-r-00020-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:50    9290089 elb/plaintext/2015/01/04/part-r-00021-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:50    7896339 elb/plaintext/2015/01/04/part-r-00022-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    8321364 elb/plaintext/2015/01/04/part-r-00023-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51          0 elb/plaintext/2015/01/04_$folder$
2016-11-23 17:54:51    7641062 elb/plaintext/2015/01/05/part-r-00024-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51   10253377 elb/plaintext/2015/01/05/part-r-00025-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    8502765 elb/plaintext/2015/01/05/part-r-00026-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51   11518464 elb/plaintext/2015/01/05/part-r-00027-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    7945189 elb/plaintext/2015/01/05/part-r-00028-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    7864475 elb/plaintext/2015/01/05/part-r-00029-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51          0 elb/plaintext/2015/01/05_$folder$
2016-11-23 17:54:51   11342140 elb/plaintext/2015/01/06/part-r-00030-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    8063755 elb/plaintext/2015/01/06/part-r-00031-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52    9387508 elb/plaintext/2015/01/06/part-r-00032-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52    9732343 elb/plaintext/2015/01/06/part-r-00033-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52   11510326 elb/plaintext/2015/01/06/part-r-00034-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52    9148117 elb/plaintext/2015/01/06/part-r-00035-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52          0 elb/plaintext/2015/01/06_$folder$
2016-11-23 17:54:52    8402024 elb/plaintext/2015/01/07/part-r-00036-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52    8282860 elb/plaintext/2015/01/07/part-r-00037-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52   11575283 elb/plaintext/2015/01/07/part-r-00038-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:53    8149059 elb/plaintext/2015/01/07/part-r-00039-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:53   10037269 elb/plaintext/2015/01/07/part-r-00040-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:53   10019678 elb/plaintext/2015/01/07/part-r-00041-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:53          0 elb/plaintext/2015/01/07_$folder$
2016-11-23 17:54:53          0 elb/plaintext/2015/01_$folder$
2016-11-23 17:54:53          0 elb/plaintext/2015_$folder$
```

#### ALTER TABLE ADD PARTITION 실행
<a name="run-alter-table-add-partition"></a>

데이터가 Hive 형식이 아니므로 `MSCK REPAIR TABLE` 명령을 사용하여 테이블을 생성한 후 테이블에 파티션을 추가합니다. 그 대신 [ALTER TABLE ADD PARTITION](alter-table-add-partition.md) 명령을 사용하여 각 파티션을 수동으로 추가할 수 있습니다. 예를 들어 s3://athena-examples-*myregion*/elb/plaintext/2015/01/01/에 데이터를 로드하려면 다음 쿼리를 실행합니다. 각 Amazon S3 폴더에 대해 별도의 파티션 열이 필요하지 않으며, 파티션 키 값이 Amazon S3 키와 다를 수 있습니다.

```
ALTER TABLE elb_logs_raw_native_part ADD PARTITION (dt='2015-01-01') location 's3://athena-examples-us-west-1/elb/plaintext/2015/01/01/'
```

파티션이 이미 있는 경우 오류(파티션이 이미 있습니다.)가 수신됩니다. 이 오류를 방지하기 위해 `IF NOT EXISTS` 절을 사용할 수 있습니다. 자세한 내용은 [ALTER TABLE ADD PARTITION](alter-table-add-partition.md) 섹션을 참조하세요. 파티션을 제거하려면 [ALTER TABLE DROP PARTITION](alter-table-drop-partition.md)을 사용합니다.

## 파티션 프로젝션 고려
<a name="partitions-partition-projection"></a>

파티션을 직접 관리하지 않으려면 파티션 프로젝션을 사용합니다. 파티션 프로젝션은 구조가 미리 알려진 고도로 분할된 테이블에 대한 옵션입니다. 파티션 프로젝션에서 파티션 값 및 위치는 메타데이터 리포지토리에서 읽지 않고 구성하는 테이블 속성에서 계산됩니다. 인메모리 계산은 원격 조회보다 빠르기 때문에 파티션 프로젝션을 사용하면 쿼리 런타임을 크게 줄일 수 있습니다.

자세한 내용은 [Amazon Athena에서 파티션 프로젝션 사용](partition-projection.md) 섹션을 참조하세요.

## 추가 리소스
<a name="partitions-additional-resources"></a>
+ Firehose 데이터의 분할 옵션에 대한 자세한 내용은 [Amazon Data Firehose 예제](partition-projection-kinesis-firehose-example.md) 섹션을 참조하세요.
+ [JDBC 드라이버](connect-with-jdbc.md)를 사용하여 파티션 추가를 자동화할 수도 있습니다.
+ CTAS 및 INSERT INTO를 사용하여 데이터 세트를 분할할 수 있습니다. 자세한 내용은 [ETL 및 데이터 분석에 CTAS 및 INSERT INTO 사용](ctas-insert-into-etl.md) 섹션을 참조하세요.

# Amazon Athena에서 파티션 프로젝션 사용
<a name="partition-projection"></a>

Athena에서 파티션 프로젝션을 사용하여 고도로 분할된 테이블의 쿼리 처리 속도를 높이고 파티션 관리를 자동화할 수 있습니다.

파티션 프로젝션에서 Athena는 AWS Glue에서 테이블에 직접 구성하는 테이블 속성에서 파티션 값 및 위치를 계산합니다. 테이블 속성을 사용하면 Athena는 필요한 파티션 정보를 '프로젝션'하거나 결정할 수 있으므로 AWS Glue Data Catalog에서 시간이 많이 걸리는 메타데이터를 검색하지 않아도 됩니다. 메모리 내 작업은 주로 원격 작업보다 빠르기 때문에 파티션 프로젝션은 고도로 분할된 테이블에 대한 쿼리의 실행 시간을 줄일 수 있습니다. 쿼리 및 기본 데이터의 특정 특성에 따라 파티션 프로젝션은 파티션 메타데이터 검색에 제한되는 쿼리에 대한 쿼리 실행 시간을 크게 줄일 수 있습니다.

## 파티션 정리 및 파티션 프로젝션 이해
<a name="partition-projection-pruning-vs-projection"></a>

파티션 정리는 메타데이터를 수집하여 쿼리에 적용되는 파티션으로만 해당 메타데이터를 “정리”합니다. 이렇게 하면 종종 쿼리 속도가 높아집니다. Athena는 파티션 프로젝션용으로 구성된 테이블을 포함하여 파티션 열이 있는 모든 테이블에 대해 파티션 정리를 사용합니다.

일반적으로 쿼리를 처리할 때 Athena는 파티션 정리를 수행하기 전에 AWS Glue Data Catalog에 대한 `GetPartitions` 호출을 수행합니다. 테이블에 많은 수의 파티션이 있는 경우 `GetPartitions`를 사용하면 성능에 부정적인 영향을 줄 수 있습니다. 이를 방지하기 위해 파티션 프로젝션을 사용할 수 있습니다. 파티션 프로젝션을 사용하면 파티션 프로젝션 구성이 파티션 자체를 빌드하는 데 필요한 모든 정보를 Athena에 제공하므로 Athena는 `GetPartitions`를 호출하지 않아도 됩니다.

## 파티션 프로젝션을 사용하는 방법
<a name="partition-projection-using"></a>

파티션 프로젝션을 사용하려면 AWS Glue Data Catalog 또는 [외부 Hive 메타스토어](connect-to-data-source-hive.md)의 테이블 속성에서 각 파티션 열에 대한 파티션 값 및 프로젝션 형식의 범위를 지정합니다. 테이블의 이러한 사용자 지정 속성을 사용하면 Athena가 테이블에서 쿼리를 실행할 때 예상되는 파티션 패턴을 알 수 있습니다. 쿼리를 실행하는 동안 Athena는 AWS Glue Data Catalog 또는 외부 Hive 메타스토어에서 파티션 값을 검색하는 대신 이 정보를 사용하여 파티션 값을 프로젝션합니다. 이렇게 하면 쿼리 실행 시간이 단축될 뿐만 아니라 Athena, AWS Glue 또는 외부 Hive 메타스토어에 파티션을 수동으로 만들 필요가 없으므로 파티션 관리도 자동화할 수 있습니다.

**중요**  
테이블에서 파티션 프로젝션을 활성화하면 Athena는 AWS Glue Data Catalog 또는 Hive 메타스토어의 테이블에 등록된 모든 파티션 메타데이터를 무시합니다.

## 일부 사용 사례
<a name="partition-projection-use-cases"></a>

파티션 프로젝션이 유용한 시나리오는 다음과 같습니다.
+ 고도로 분할된 테이블에 대한 쿼리는 원하는 만큼 빨리 완료되지 않습니다.
+ 데이터에 새 날짜 또는 시간 파티션이 생성될 때 정기적으로 테이블에 파티션을 추가합니다. 파티션 프로젝션을 사용하면 새 데이터가 도착할 때 사용할 수 있는 상대 날짜 범위를 구성할 수 있습니다.
+ Amazon S3에 고도로 분할된 데이터가 있습니다. AWS Glue Data Catalog 또는 Hive 메타스토어에서 데이터를 모델링하는 것은 실용적이지 않으며 쿼리는 데이터의 작은 부분만 읽습니다.

### 프로젝션 가능한 파티션 구조
<a name="partition-projection-known-data-structures"></a>

파티션 프로젝션은 파티션이 다음과 같은(이에 국한되지 않음) 예측 가능한 패턴을 따를 때 가장 쉽게 구성할 수 있습니다.
+ **정수** – `[1, 2, 3, 4, ..., 1000]` 또는 `[0500, 0550, 0600, ..., 2500]`과 같은 정수의 연속 시퀀스입니다.
+ **날짜** – `[20200101, 20200102, ..., 20201231]` 또는 `[1-1-2020 00:00:00, 1-1-2020 01:00:00, ..., 12-31-2020 23:00:00]`과 같은 날짜 또는 날짜/시간의 연속 시퀀스입니다.
+ **열거형 값** - 공항 코드 또는 AWS 리전과 같은 열거형 값의 유한 집합입니다.
+ **AWS 서비스 로그** - AWS 서비스 로그에는 일반적으로 AWS Glue에서 지정할 수 있고 Athena가 파티션 프로젝션에 사용할 수 있는 파티션 체계를 가진 알려진 구조가 있습니다.

### 파티션 경로 템플릿을 사용자 지정하는 방법
<a name="partition-projection-custom-s3-storage-locations"></a>

기본적으로 Athena는 `s3://amzn-s3-demo-bucket/<table-root>/partition-col-1=<partition-col-1-val>/partition-col-2=<partition-col-2-val>/` 양식을 사용하여 파티션 위치를 작성하지만 데이터가 다르게 구성된 경우 Athena는 이 경로 템플릿을 사용자 지정할 수 있는 메커니즘을 제공합니다. 단계는 [사용자 지정 S3 스토리지 위치를 지정하는 방법](partition-projection-setting-up.md#partition-projection-specifying-custom-s3-storage-locations)를 참조하세요.

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

다음 사항을 고려하세요.
+ 파티션 프로젝션을 사용할 경우 AWS Glue 또는 외부 Hive 메타스토어에서 수동으로 파티션을 지정할 필요가 없습니다.
+ 테이블에서 파티션 프로젝션을 활성화하면 Athena는 해당 테이블에 대한 AWS Glue Data Catalog 또는 외부 Hive 메타스토어의 파티션 메타데이터를 무시합니다.
+ Amazon S3에 프로젝션된 파티션이 없는 경우 Athena는 계속해서 파티션을 프로젝션합니다. Athena가 오류를 발생시키지는 않지만 데이터가 반환되지 않습니다. 그러나 너무 많은 파티션이 비어 있으면 기존 AWS Glue 파티션에 비해 성능이 느려질 수 있습니다. 프로젝션된 파티션의 절반 이상이 비어 있으면 기존 파티션을 사용하는 것이 좋습니다.
+ 파티션 프로젝션에 대해 정의된 범위 한계를 벗어난 값에 대한 쿼리는 오류를 반환하지 않습니다. 그 대신 쿼리가 실행되지만 0개의 행을 반환합니다. 예를 들어 2,020으로 시작하고 `'projection.timestamp.range'='2020/01/01,NOW'`로 정의된 시간 관련 데이터가 있는 경우 `SELECT * FROM table-name WHERE timestamp = '2019/02/02'` 같은 쿼리는 성공적으로 완료되지만 0개의 행을 반환합니다.
+ Athena를 통해 테이블을 쿼리할 때만 파티션 프로젝션을 사용할 수 있습니다. Amazon Redshift Spectrum, Athena for Spark, Amazon EMR 등의 다른 서비스를 통해 동일한 테이블을 읽는 경우 표준 파티션 메타데이터가 사용됩니다.
+ 파티션 프로젝션은 DML 전용 기능이므로 `SHOW PARTITIONS`에서는 Athena에 의해 프로젝션되었지만 AWS Glue 카탈로그 또는 외부 Hive 메타스토어에 등록되지 않은 파티션은 나열하지 않습니다.
+ Athena는 파티션 프로젝션을 위한 구성으로 뷰의 테이블 속성을 사용하지 않습니다. 이 제한을 해결하려면 뷰가 참조하는 테이블의 테이블 속성에서 파티션 프로젝션을 구성하고 활성화합니다.

## 비디오
<a name="partition-projection-video"></a>

다음 비디오는 Athena에서 쿼리의 성능을 향상시키기 위해 파티션 프로젝션을 사용하는 방법을 보여줍니다.

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


**Topics**
+ [파티션 정리 및 파티션 프로젝션 이해](#partition-projection-pruning-vs-projection)
+ [파티션 프로젝션을 사용하는 방법](#partition-projection-using)
+ [일부 사용 사례](#partition-projection-use-cases)
+ [고려 사항 및 제한 사항](#partition-projection-considerations-and-limitations)
+ [비디오](#partition-projection-video)
+ [파티션 프로젝션 설정](partition-projection-setting-up.md)
+ [파티션 프로젝션에 지원되는 형식](partition-projection-supported-types.md)
+ [동적 ID 분할 사용](partition-projection-dynamic-id-partitioning.md)
+ [Amazon Data Firehose 예제](partition-projection-kinesis-firehose-example.md)

# 파티션 프로젝션 설정
<a name="partition-projection-setting-up"></a>

테이블의 속성에서 파티션 프로젝션을 설정하는 과정은 두 단계로 이루어집니다.

1. 각 파티션 열에 대한 데이터 범위 및 관련 패턴을 지정하거나 사용자 지정 템플릿을 사용합니다.

1. 테이블에 대해 파티션 프로젝션을 활성화합니다.

**참고**  
기존 테이블에 파티션 프로젝션 속성을 추가하기 전에 파티션 프로젝션 속성을 설정하려는 파티션 열이 테이블 스키마에 이미 있어야 합니다. 파티션 열이 아직 없는 경우 기존 테이블에 파티션 열을 수동으로 추가해야 합니다. AWS Glue에서는 이 단계를 자동으로 수행하지 않습니다.

이 단원에서는 AWS Glue에 대해 테이블 속성을 설정하는 방법을 보여줍니다. 이러한 속성을 설정하기 위해 AWS Glue 콘솔, Athena [CREATE TABLE](create-table.md) 쿼리 또는 [AWS Glue API](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-api.html) 작업을 사용할 수 있습니다. 다음 절차에서는 AWS Glue 콘솔에서 속성을 설정하는 방법을 보여줍니다.

**AWS Glue 콘솔을 사용하여 파티션 프로젝션을 구성하고 활성화하려면**

1. AWS Management Console에 로그인하여 [https://console.aws.amazon.com/glue/](https://console.aws.amazon.com/glue/)에서 AWS Glue 콘솔을 엽니다.

1. **테이블** 탭을 선택합니다.

   **테이블** 탭에서 기존 테이블을 편집하거나 **테이블 추가**를 선택하여 새 테이블을 생성할 수 있습니다. 수동으로 또는 크롤러를 사용하여 테이블을 추가하는 방법에 대한 자세한 내용은 *AWS Glue 개발자 안내서*의 [AWS Glue 콘솔에서 테이블 관련 작업](https://docs.aws.amazon.com/glue/latest/dg/console-tables.html)을 참조하세요.

1. 테이블 목록에서 편집하려는 테이블에 대한 링크를 선택합니다.  
![\[AWS Glue 콘솔에서 편집할 테이블을 선택합니다.\]](http://docs.aws.amazon.com/ko_kr/athena/latest/ug/images/partition-projection-1.png)

1. **Actions**(작업), **Edit table**(테이블 편집)을 선택합니다.

1. **Edit table**(테이블 편집) 페이지의 **Table properties**(테이블 속성) 섹션에서 분할된 각 열에 대해 다음 키-값 페어를 추가합니다.

   1. **키**에 `projection.columnName.type`을 추가합니다.

   1. **값**에 지원되는 형식 `enum`, `integer`, `date`, `injected` 중 하나를 추가합니다. 자세한 내용은 [파티션 프로젝션에 지원되는 형식](partition-projection-supported-types.md) 단원을 참조하세요.

1. [파티션 프로젝션에 지원되는 형식](partition-projection-supported-types.md)의 지침을 따르고, 구성 요구 사항에 따라 추가적인 키-값 페어를 추가합니다.

   다음 예제 테이블 구성은 파티션 프로젝션에 대한 `year` 열을 구성하여 반환할 수 있는 값을 2010에서 2016까지의 범위로 제한합니다.  
![\[AWS Glue 콘솔 테이블 속성에서 파티션 열에 대한 파티션 프로젝션 구성.\]](http://docs.aws.amazon.com/ko_kr/athena/latest/ug/images/partition-projection-3.png)

1. 키-값 페어를 추가하여 파티션 프로젝션을 활성화합니다. **키**에 `projection.enabled`를 입력하고 **값**에 `true`를 입력합니다.
**참고**  
`projection.enabled`을 `false`로 설정하여 언제든지 이 테이블에서 파티션 프로젝션을 비활성화할 수 있습니다.

1. 작업을 마쳤으면 **저장**을 선택합니다.

1. Athena 쿼리 편집기에서 테이블에 대해 구성한 열을 테스트 쿼리합니다.

   다음 예제 쿼리는 `SELECT DISTINCT`를 사용하여 `year` 열에서 고유한 값을 반환합니다. 데이터베이스에는 1987년부터 2016년까지 데이터가 포함되어 있지만 `projection.year.range` 속성은 반환되는 값을 2010년에서 2016년까지로 제한합니다.  
![\[파티션 프로젝션을 사용하는 열 쿼리.\]](http://docs.aws.amazon.com/ko_kr/athena/latest/ug/images/partition-projection-5.png)
**참고**  
`projection.enabled`를 `true`로 설정했지만 하나 이상의 파티션 열을 구성하지 못하면 다음과 같은 오류 메시지가 나타납니다.  
`HIVE_METASTORE_ERROR: Table database_name.table_name is configured for partition projection, but the following partition columns are missing projection configuration: [column_name] (table database_name.table_name)`.

## 사용자 지정 S3 스토리지 위치를 지정하는 방법
<a name="partition-projection-specifying-custom-s3-storage-locations"></a>

AWS Glue에서 테이블 속성을 편집할 때 프로젝션된 파티션에 대한 사용자 지정 Amazon S3 경로 템플릿을 지정할 수도 있습니다. 사용자 지정 템플릿을 사용하면 Athena가 일반적인 `.../column=value/...` 패턴을 따르지 않는 사용자 지정 Amazon S3 파일 위치에 파티션 값을 올바르게 매핑할 수 있습니다.

사용자 지정 템플릿을 사용하는 것은 선택 사항입니다. 그러나 사용자 지정 템플릿을 사용하는 경우 템플릿에 각 파티션 열에 대한 자리 표시자를 포함시켜야 합니다. 분할된 데이터 파일이 파티션별 ‘폴더’에 상주하도록 템플릿 지정된 위치는 슬래시로 끝나야 합니다.

**사용자 지정 파티션 위치 템플릿을 지정하려면**

1. [AWS Glue 콘솔을 사용하여 파티션 프로젝션을 구성하고 활성화](#partition-projection-setting-up-procedure)하는 단계에 따라 다음과 같이 사용자 지정 템플릿을 지정하는 키-값 페어를 추가합니다.

   1. **키**에 `storage.location.template`를 입력합니다.

   1. **값**에서 모든 파티션 열에 대한 자리 표시자를 포함하는 위치를 지정합니다. 각 자리 표시자(및 S3 경로 자체)가 단일 슬래시로 종료되었는지 확인합니다.

      다음 예제 템플릿 값은 테이블에 파티션 열 `a`, `b` 및 `c`가 있다고 가정합니다.

      ```
      s3://amzn-s3-demo-bucket/table_root/a=${a}/${b}/some_static_subdirectory/${c}/      
      ```

      ```
      s3://amzn-s3-demo-bucket/table_root/c=${c}/${b}/some_static_subdirectory/${a}/${b}/${c}/${c}/      
      ```

      같은 테이블의 경우 다음 예제 템플릿 값은 열 `c`에 대한 자리 표시자가 포함되어 있지 않기 때문에 유효하지 않습니다.

      ```
      s3://amzn-s3-demo-bucket/table_root/a=${a}/${b}/some_static_subdirectory/         
      ```

1. **Apply(적용)**를 선택합니다.

# 파티션 프로젝션에 지원되는 형식
<a name="partition-projection-supported-types"></a>

테이블에는 `enum`, `integer`, `date,` 또는 `injected` 파티션 열 형식의 조합이 있을 수 있습니다.

## 열거형 형식
<a name="partition-projection-enum-type"></a>

값이 열거형 집합의 멤버(예: 공항 코드 또는 AWS 리전)인 파티션 열의 `enum` 형식을 사용합니다.

테이블에서 다음과 같이 파티션 속성을 정의합니다.


****  

| 속성 이름 | 예제 값 | 설명 | 
| --- | --- | --- | 
| projection.columnName.type |  `enum`  | 필수 사항입니다. columnName 열에 사용할 프로젝션 형식입니다. 열거형 형식의 사용을 나타내기 위해서는 값이 enum이어야 합니다(대소문자 구분 안 함). 선행 및 후행 공백을 사용할 수 있습니다. | 
| projection.columnName.values |  `A,B,C,D,E,F,G,Unknown`  | 필수 사항입니다. ColumnName 열에 대한 열거형 파티션 값의 쉼표로 구분된 목록입니다. 공백은 열거형 값의 일부로 간주됩니다. | 

**참고**  
가장 좋은 방법은 `enum` 기반 파티션 프로젝션 사용을 수십 개 이하로 제한하는 것입니다 `enum` 프로젝션에 대해 구체적인 제한은 없지만 테이블의 메타데이터 총 크기는 gzip 압축 시 약 1MB의 AWS Glue 제한을 초과할 수 없습니다. 이 제한은 열 이름, 위치, 스토리지 형식 등과 같은 테이블의 주요 부분에서 공유됩니다. 자신이 `enum` 프로젝션에 수십 개 이상의 고유 ID를 사용하고 있다면 대리 필드에서 더 적은 수의 고유 값으로 버킷팅하는 등의 대안적 방법을 고려하는 것이 좋습니다. 카디널리티를 포기함으로써 `enum` 필드에서 고유 값의 수를 제어할 수 있습니다.

## 정수 형식
<a name="partition-projection-integer-type"></a>

가능한 값을 정의된 범위 내의 정수로 해석할 수 있는 파티션 열에 대해 정수 형식을 사용합니다. 프로젝션 정수 열은 현재 Java 부호 있는 long(-263\$1263-1 포함)의 범위로 제한됩니다.


****  

| 속성 이름 | 예제 값 | 설명 | 
| --- | --- | --- | 
| projection.columnName.type |  `integer`  | 필수 사항입니다. columnName 열에 사용할 프로젝션 형식입니다. 정수 형식의 사용을 나타내기 위해서는 값이 integer여야 합니다(대소문자 구분 안 함). 선행 및 후행 공백을 사용할 수 있습니다. | 
| projection.columnName.range |  `0,10` `-1,8675309` `0001,9999`  | 필수 사항입니다. columnName 열에 대한 쿼리에서 반환할 최소 및 최대 범위 값을 제공하는 두 요소의 쉼표로 구분된 목록입니다. 값을 하이픈이 아닌 쉼표로 구분해야 합니다. 이 값은 포함되며 음수일 수 있으며 선행 0을 포함할 수 있습니다. 선행 및 후행 공백을 사용할 수 있습니다. | 
| projection.columnName.interval |  `1` `5`  | 선택 사항. columnName 열에 대한 연속 파티션 값 사이의 간격을 지정하는 양의 정수입니다. 예를 들어 interval 값이 “1"인 range 값 “1,3"은 1, 2, 3 값을 생성합니다. interval 값이 “2"인 동일한 range 값은 값 1과 3을 생성하며 2를 건너뜁니다. 선행 및 후행 공백을 사용할 수 있습니다. 기본값은 1입니다. | 
| projection.columnName.digits |  `1` `5`  | 선택 사항. columnName 열에 대한 파티션 값의 최종 표시에 포함할 자릿수를 지정하는 양의 정수입니다. 예를 들어 digits 값이 “1"인 range 값 “1,3"은 1, 2, 3 값을 생성합니다. digits 값이 “2"인 동일한 range 값은 01, 02 및 03 값을 생성합니다. 선행 및 후행 공백을 사용할 수 있습니다. 기본값은 고정 자릿수와 선행 0이 없습니다. | 

## 날짜 형식
<a name="partition-projection-date-type"></a>

정의된 범위 내에서 값을 날짜(선택적 시간 포함)로 해석할 수 있는 파티션 열에 대해 날짜 형식을 사용합니다.

**중요**  
프로젝션 날짜 열은 쿼리 실행 시 UTC(협정 세계 표준시)로 생성됩니다.


****  

| 속성 이름 | 예제 값 | 설명 | 
| --- | --- | --- | 
| projection.columnName.type |  `date`  | 필수 사항입니다. columnName 열에 사용할 프로젝션 형식입니다. 날짜 형식의 사용을 나타내기 위해서는 값이 date여야 합니다(대소문자 구분 안 함). 선행 및 후행 공백을 사용할 수 있습니다. | 
| projection.columnName.range |  `201701,201812` `01-01-2010,12-31-2018` `NOW-3YEARS,NOW` `201801,NOW+1MONTH`  |  필수 사항입니다. *columnName* 열에 대한 최소 및 최대 `range` 값을 제공하는 두 요소의 쉼표로 구분된 목록입니다. 이 값은 포함되며 Java `java.time.*` 날짜 형식과 호환되는 모든 형식을 사용할 수 있습니다. 최소값과 최대값 모두 동일한 형식을 사용해야 합니다. `.format` 특성에 지정된 형식은 이러한 값에 사용되는 형식이어야 합니다. 이 열에는 이 정규식 패턴으로 서식이 지정된 상대 날짜 문자열도 포함될 수 있습니다. `\s*NOW\s*(([\+\-])\s*([0-9]+)\s*(YEARS?\|MONTHS?\|WEEKS?\|DAYS?\|HOURS?\|MINUTES?\|SECONDS?)\s*)?` 공백은 허용되지만 날짜 리터럴은 날짜 문자열 자체의 일부로 간주됩니다.  | 
| projection.columnName.format |  `yyyyMM` `dd-MM-yyyy` `dd-MM-yyyy-HH-mm-ss`  | 필수 사항입니다. Java 날짜 형식 [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)를 기반으로 하는 날짜 형식 문자열입니다. 지원되는 모든 Java.time.\$1 형식일 수 있습니다. | 
| projection.columnName.interval |  `1` `5`  |  *columnName에* 열에 대한 연속 파티션 값 사이의 간격을 지정하는 양의 정수입니다. 예를 들어 `interval` 값이 `1`이고 `interval.unit` 값이 `MONTHS`인 `range`값 `2017-01,2018-12`는 2017-01, 2017-02, 2017-03 등의 값을 생성합니다. `interval` 값이 `2`이고 `interval.unit` 값이 `MONTHS`인 동일한 `range` 값은 2017-01, 2017-03, 2017-05 등의 값을 생성합니다. 선행 및 후행 공백을 사용할 수 있습니다. 제공된 날짜가 하루 또는 한 달 정밀도인 경우 `interval`은 선택 사항이며 기본값은 각각 1일 또는 1개월입니다. 그렇지 않으면 `interval`이 필요합니다.  | 
| projection.columnName.interval.unit |  `YEARS` `MONTHS` `WEEKS` `DAYS` `HOURS` `MINUTES` `SECONDS` `MILLIS`  |  [ChronoUnit](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/ChronoUnit.html)의 직렬화된 형식을 나타내는 시간 단위 단어입니다. 가능한 값은 `YEARS`, `MONTHS`, `WEEKS`, `DAYS`, `HOURS`, `MINUTES`, `SECONDS` 또는 `MILLIS`입니다. 이러한 값은 대/소문자를 구분합니다. 제공된 날짜가 하루 또는 한 달 정밀도인 경우 `interval.unit`은 선택 사항이며 기본값은 각각 1일 또는 1개월입니다. 그렇지 않으면 `interval.unit`이 필요합니다.  | 

**Example -월별 분할**  
다음 예제 테이블 구성은 2015년부터 현재까지의 데이터를 월별로 분할합니다.  

```
'projection.month.type'='date', 
'projection.month.format'='yyyy-MM', 
'projection.month.interval'='1', 
'projection.month.interval.unit'='MONTHS', 
'projection.month.range'='2015-01,NOW', 
...
```

## 삽입 형식
<a name="partition-projection-injected-type"></a>

일부 논리적 범위 내에서 절차에 따라 생성될 수 없지만 쿼리의 `WHERE` 절에서 단일 값으로 제공되는 가능한 값을 가진 파티션 열에 대해 삽입된 형식을 사용하세요.

다음 사항을 명심해야 합니다.
+ 삽입된 각 열에 대해 필터 식이 제공되지 않으면 삽입된 열에 대한 쿼리가 실패합니다.
+ 주입된 열의 필터 식에 대해 여러 값이 있는 쿼리는 값이 분리된 경우에만 성공합니다.
+ `string` 형식의 열만 지원됩니다.
+ 주입된 파티션 열과 함께 `WHERE IN` 절을 사용하는 경우 `IN` 목록에서 지정할 수 있는 값은 1,000개로 제한됩니다. 주입된 열에 대해 파티션이 1,000개를 초과하는 데이터세트를 쿼리하려면 쿼리를 여러 개의 작은 쿼리로 분할한 후(각각 `WHERE IN` 절에서 최대 1,000개의 값을 보유함) 결과를 집계합니다.


****  

| 속성 이름 | 값 | 설명 | 
| --- | --- | --- | 
| projection.columnName.type |  `injected`  | 필수 사항입니다. columnName 열에 사용할 프로젝션 형식입니다. string 형식만 지원됩니다. 지정된 값은 injected여야 합니다(대소문자 구분 안 함). 선행 및 후행 공백을 사용할 수 있습니다. | 

자세한 내용은 [`injected` 프로젝션 유형을 사용해야 하는 경우](partition-projection-dynamic-id-partitioning.md#partition-projection-injection) 섹션을 참조하세요.

# 동적 ID 분할 사용
<a name="partition-projection-dynamic-id-partitioning"></a>

데이터가 카디널리티가 높은 속성으로 파티션되거나 값을 미리 알 수 없는 경우 `injected` 프로젝션 유형을 사용할 수 있습니다. 이러한 속성의 예로 사용자 이름과 디바이스 또는 제품의 ID가 있습니다. `injected` 프로젝션 유형을 사용하여 파티션 키를 구성하면 Athena는 쿼리 자체의 값을 사용하여 읽을 파티션 세트를 계산합니다.

다음 조건을 충족해야 Athena가 `injected` 프로젝션 유형으로 구성된 파티션 키가 있는 테이블에서 쿼리를 실행할 수 있습니다.
+ 쿼리에는 파티션 키 값이 하나 이상 포함해야 합니다.
+ 값은 데이터를 읽지 않고도 평가할 수 있는 리터럴 또는 표현식이어야 합니다.

이러한 기준 중 하나라도 충족되지 않으면 쿼리가 실패하고 다음 오류가 발생합니다.

CONSTRAINT\$1VIOLATION: 삽입된 프로젝션 파티션 열 *column\$1name*에는 WHERE 절에 하나 이상의 정적 같음 조건만 포함되어야 합니다.

## `injected` 프로젝션 유형을 사용해야 하는 경우
<a name="partition-projection-injection"></a>

IoT 디바이스의 이벤트로 구성되고 디바이스 ID로 파티션된 데이터 세트가 있다고 가정해 보겠습니다. 다음은 이 데이터 세트의 특성입니다.
+ 디바이스 ID는 무작위로 생성됩니다.
+ 새 디바이스는 자주 프로비저닝됩니다.
+ 현재 수십만 개의 디바이스가 있으며 미래에는 수백만 개가 될 것입니다.

기존 메타스토어로는 이 데이터 세트를 관리하기 어렵습니다. 데이터 스토리지와 메타스토어 간에 파티션을 동기화된 상태로 유지하기가 어렵고 쿼리를 계획하는 동안 파티션 필터링이 느려질 수 있습니다. 그러나 파티션 프로젝션을 사용하고 `injected` 프로젝션 유형을 사용하도록 테이블을 구성하면 메타스토어에서 파티션을 관리할 필요가 없고 쿼리에서 파티션 메타데이터를 조회할 필요가 없다는 두 가지 이점이 있습니다.

다음 `CREATE TABLE` 예제에서는 방금 설명한 디바이스 이벤트 데이터 세트에 대한 테이블을 생성합니다. 테이블에서는 injected 프로젝션 유형을 사용합니다.

```
CREATE EXTERNAL TABLE device_events (
  event_time TIMESTAMP,
  data STRING,
  battery_level INT
)
PARTITIONED BY (
  device_id STRING
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
  "projection.enabled" = "true",
  "projection.device_id.type" = "injected",
  "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${device_id}"
)
```

다음 예제 쿼리는 12시간 동안 3개의 특정 디바이스에서 수신한 이벤트 수를 조회합니다.

```
SELECT device_id, COUNT(*) AS events
FROM device_events
WHERE device_id IN (
  '4a770164-0392-4a41-8565-40ed8cec737e',
  'f71d12cf-f01f-4877-875d-128c23cbde17',
  '763421d8-b005-47c3-ba32-cc747ab32f9a'
)
AND event_time BETWEEN TIMESTAMP '2023-11-01 20:00' AND TIMESTAMP '2023-11-02 08:00'
GROUP BY device_id
```

이 쿼리를 실행하면 Athena는 `device_id` 파티션 키에 대한 3개의 값을 확인하고 이들 값을 사용하여 파티션 위치를 계산합니다. Athena는 `storage.location.template` 속성 값을 사용하여 다음 위치를 생성합니다.
+ `s3://amzn-s3-demo-bucket/prefix/4a770164-0392-4a41-8565-40ed8cec737e`
+ `s3://amzn-s3-demo-bucket/prefix/f71d12cf-f01f-4877-875d-128c23cbde17`
+ `s3://amzn-s3-demo-bucket/prefix/763421d8-b005-47c3-ba32-cc747ab32f9a`

파티션 프로젝션 구성에서 `storage.location.template` 속성을 제외하면 Athena는 Hive 스타일 파티셔닝을 사용하여 `LOCATION`의 값(예: `s3://amzn-s3-demo-bucket/prefix/device_id=4a770164-0392-4a41-8565-40ed8cec737e`)을 기준으로 파티션 위치를 예상합니다.

# Amazon Data Firehose 예제
<a name="partition-projection-kinesis-firehose-example"></a>

Firehose를 사용하여 데이터를 Amazon S3로 전송하는 경우 기본 구성은 다음 예제와 같은 키를 사용하여 객체를 작성합니다.

```
s3://amzn-s3-demo-bucket/prefix/yyyy/MM/dd/HH/file.extension
```

새 데이터가 수신될 때 AWS Glue Data Catalog에 추가하는 대신에 쿼리할 때 파티션을 자동으로 찾는 Athena 테이블을 생성하려면 파티션 프로젝션을 사용할 수 있습니다.

다음 `CREATE TABLE` 예제에서는 기본 Firehose 구성을 사용합니다.

```
CREATE EXTERNAL TABLE my_ingested_data (
 ...
)
...
PARTITIONED BY (
 datehour STRING
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
 "projection.enabled" = "true",
 "projection.datehour.type" = "date",
 "projection.datehour.format" = "yyyy/MM/dd/HH",
 "projection.datehour.range" = "2021/01/01/00,NOW",
 "projection.datehour.interval" = "1",
 "projection.datehour.interval.unit" = "HOURS",
 "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${datehour}/"
)
```

`CREATE TABLE` 문의 `TBLPROPERTIES` 절은 Athena에 다음을 알려줍니다.
+ 테이블을 쿼리할 때 파티션 프로젝션 사용
+ 파티션 키 `datehour`는 `date` 형식입니다(선택적 시간 포함).
+ 날짜 형식 지정 방법
+ 날짜 시간 범위입니다. 값을 하이픈이 아닌 쉼표로 구분해야 합니다.
+ Amazon S3에 대한 데이터를 찾을 수 있는 위치

테이블을 쿼리할 때 Athena는 `datehour`에 대한 값을 계산하고 스토리지 위치 템플릿을 사용하여 파티션 위치 목록을 생성합니다.

**Topics**
+ [`date` 형식을 사용하는 방법](partition-projection-kinesis-firehose-example-using-the-date-type.md)
+ [파티션 키를 선택하는 방법](partition-projection-kinesis-firehose-example-choosing-partition-keys.md)
+ [사용자 지정 접두사 및 동적 파티셔닝을 사용하는 방법](partition-projection-kinesis-firehose-example-using-custom-prefixes-and-dynamic-partitioning.md)

# `date` 형식을 사용하는 방법
<a name="partition-projection-kinesis-firehose-example-using-the-date-type"></a>

프로젝션된 파티션 키에 대해 `date` 형식을 사용하는 경우 범위를 지정해야 합니다. Firehose 전송 스트림이 생성되기 전의 날짜에 대한 데이터가 없으므로 생성 날짜를 시작으로 사용할 수 있습니다. 향후 날짜에 대한 데이터가 없으므로 특수 토큰 `NOW`를 종료로 사용할 수 있습니다.

`CREATE TABLE` 예에서 시작 날짜는 2021년 1월 1일 UTC 자정으로 지정됩니다.

**참고**  
Athena가 기존 파티션만 찾을 수 있도록 데이터가 최대한 가깝게 일치하는 범위를 구성합니다.

예제 테이블에서 쿼리가 실행되면 Athena는 값을 생성하는 범위와 조합된 `datehour` 파티션 키 조건을 사용합니다. 다음과 같은 쿼리를 가정합니다.

```
SELECT *
FROM my_ingested_data
WHERE datehour >= '2020/12/15/00'
AND datehour < '2021/02/03/15'
```

`SELECT` 쿼리의 첫 번째 조건은 `CREATE TABLE` 문에 의해 지정된 날짜 범위의 시작 이전 날짜를 사용합니다. 파티션 프로젝션 구성에서는 2021년 1월 1일 이전 날짜의 파티션을 지정하지 않으므로 Athena는 다음 위치에서만 데이터를 찾고 쿼리의 이전 날짜는 무시합니다.

```
s3://amzn-s3-demo-bucket/prefix/2021/01/01/00/
s3://amzn-s3-demo-bucket/prefix/2021/01/01/01/
s3://amzn-s3-demo-bucket/prefix/2021/01/01/02/
...
s3://amzn-s3-demo-bucket/prefix/2021/02/03/12/
s3://amzn-s3-demo-bucket/prefix/2021/02/03/13/
s3://amzn-s3-demo-bucket/prefix/2021/02/03/14/
```

마찬가지로 쿼리가 2021년 2월 3일 15:00 이전의 날짜와 시간에 실행된 경우 마지막 파티션은 쿼리 조건의 날짜와 시간이 아니라 현재 날짜와 시간을 반영합니다.

가장 최근 데이터를 쿼리하려는 경우, 다음 예와 같이 Athena가 미래 날짜를 생성하지 않고 시작 `datehour`만 지정한다는 사실을 활용할 수 있습니다.

```
SELECT *
FROM my_ingested_data
WHERE datehour >= '2021/11/09/00'
```

# 파티션 키를 선택하는 방법
<a name="partition-projection-kinesis-firehose-example-choosing-partition-keys"></a>

파티션 프로젝션이 파티션 위치를 파티션 키에 매핑하는 방법을 지정할 수 있습니다. 이전 섹션의 `CREATE TABLE` 예제에서 날짜와 시간은 datehour라는 하나의 파티션 키로 결합되었지만 다른 체계도 가능합니다. 예를 들어 년, 월, 일 및 시간에 대해 별도의 파티션 키를 사용하여 테이블을 구성할 수도 있습니다.

하지만 날짜를 년, 월, 일로 분할하면 `date` 파티션 프로젝션 유형을 사용할 수 없습니다. 또 다른 방법은 시간에서 날짜를 분리하여 `date` 파티션 프로젝션 유형을 계속 활용하면서 시간 범위를 지정하는 쿼리를 더 읽기 쉽게 만드는 것입니다.

이를 염두에 두고 다음 `CREATE TABLE` 예에서는 날짜와 시간을 구분합니다. SQL에서는 `date`가 예약어이기 때문에 이 예제에서는 날짜를 나타내는 파티션 키의 이름으로 `day`를 사용합니다.

```
CREATE EXTERNAL TABLE my_ingested_data2 (
 ...
)
...
PARTITIONED BY (
 day STRING,
 hour INT
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
 "projection.enabled" = "true",
 "projection.day.type" = "date",
 "projection.day.format" = "yyyy/MM/dd",
 "projection.day.range" = "2021/01/01,NOW",
 "projection.day.interval" = "1",
 "projection.day.interval.unit" = "DAYS",
 "projection.hour.type" = "integer",
 "projection.hour.range" = "0,23",
 "projection.hour.digits" = "2",
 "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${day}/${hour}/"
)
```

예제 `CREATE TABLE` 문에서 시간은 정수로 구성된 별도의 파티션 키입니다. 시간 파티션 키의 구성은 0 \$1 23의 범위를 지정하고 Athena가 파티션 위치를 생성할 때 시간을 두 자리 숫자로 형식화해야 합니다.

`my_ingested_data2` 테이블에 대한 쿼리는 다음과 같을 수 있습니다.

```
SELECT *
FROM my_ingested_data2
WHERE day = '2021/11/09'
AND hour > 3
```

## 파티션 키 및 파티션 프로젝션 데이터 형식 이해
<a name="partition-projection-kinesis-firehose-example-partition-key-types-and-partition-projection-types"></a>

첫 번째 `CREATE TABLE` 예의 `datehour` 키는 파티션 프로젝션 구성에서 `date`로 구성되지만 파티션 키의 유형은 `string`입니다. 두 번째 예의 `day`도 마찬가지입니다. 파티션 프로젝션 구성의 유형은 파티션 위치를 생성할 때 값의 형식을 지정하는 방법만 Athena에 알려줍니다. 지정한 형식은 파티션 키의 유형을 변경하지 않습니다. 쿼리에서 `datehour` 및 `day`는 `string` 형식입니다.

쿼리에 `day = '2021/11/09'`와 같은 조건이 포함된 경우 Athena는 파티션 프로젝션 구성에 지정된 날짜 형식을 사용하여 표현식의 오른쪽에 있는 문자열을 구문 분석합니다. Athena는 날짜가 구성된 범위 내에 있는지 확인한 후 날짜 형식을 다시 사용하여 저장 위치 템플릿에 날짜를 문자열로 삽입합니다.

마찬가지로 `day > '2021/11/09'`와 같은 쿼리 조건의 경우 Athena는 오른쪽을 구문 분석하고 구성된 범위 내에서 일치하는 모든 날짜 목록을 생성합니다. 그런 다음 날짜 형식을 사용하여 각 날짜를 스토리지 위치 템플릿에 삽입하여 파티션 위치 목록을 생성합니다.

`day > '2021-11-09'` 또는 `day > DATE '2021-11-09'`와 같은 조건을 쓰는 작업은 적용되지 않습니다. 첫 번째 경우에는 날짜 형식이 일치하지 않으며(포워드 슬래시 대신 하이픈에 유의) 두 번째 경우에는 데이터 형식이 일치하지 않습니다.

# 사용자 지정 접두사 및 동적 파티셔닝을 사용하는 방법
<a name="partition-projection-kinesis-firehose-example-using-custom-prefixes-and-dynamic-partitioning"></a>

Firehose는 [사용자 지정 접두사](https://docs.aws.amazon.com/firehose/latest/dev/s3-prefixes.html)와 [동적 파티셔닝](https://docs.aws.amazon.com/firehose/latest/dev/dynamic-partitioning.html)으로 구성할 수 있습니다. 이러한 기능을 사용하여 Amazon S3 키를 구성하고 사용 사례를 더 잘 지원하는 분할 체계를 설정할 수 있습니다. 이러한 분할 체계와 함께 파티션 프로젝션을 사용하여 적절하게 구성할 수도 있습니다.

예를 들어 사용자 지정 접두사 기능을 사용하여 기본 `yyyy/MM/dd/HH` 체계 대신 ISO 형식의 날짜가 있는 Amazon S3 키를 가져올 수 있습니다.

사용자 지정 접두사를 동적 파티셔닝과 결합하여 다음 예제와 같이 Firehose 메시지의 `customer_id`와 같은 속성을 추출할 수 있습니다.

```
prefix/!{timestamp:yyyy}-!{timestamp:MM}-!{timestamp:dd}/!{partitionKeyFromQuery:customer_id}/
```

Amazon S3 접두사를 사용하면 Firehose 전송 스트림에서 `s3://amzn-s3-demo-bucket/prefix/2021-11-01/customer-1234/file.extension`과 같은 키에 객체를 씁니다. 값을 미리 알 수 없으며 `customer_id`와 같은 속성의 경우 파티션 프로젝션 유형 `injected`를 사용하고 다음과 같이 `CREATE TABLE` 문을 사용할 수 있습니다.

```
CREATE EXTERNAL TABLE my_ingested_data3 (
 ...
)
...
PARTITIONED BY (
 day STRING,
 customer_id STRING
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
 "projection.enabled" = "true",
 "projection.day.type" = "date",
 "projection.day.format" = "yyyy-MM-dd",
 "projection.day.range" = "2021-01-01,NOW",
 "projection.day.interval" = "1",
 "projection.day.interval.unit" = "DAYS",
 "projection.customer_id.type" = "injected",
 "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${day}/${customer_id}/"
)
```

`injected` 유형의 파티션 키가 있는 테이블을 쿼리할 때 쿼리에 해당 파티션 키에 대한 값이 포함되어야 합니다. `my_ingested_data3` 테이블에 대한 쿼리는 다음과 같을 수 있습니다.

```
SELECT *
FROM my_ingested_data3
WHERE day BETWEEN '2021-11-01' AND '2021-11-30'
AND customer_id = 'customer-1234'
```

## 날짜 파티션 키에 DATE 형식 사용
<a name="partition-projection-kinesis-firehose-example-iso-formatted-dates"></a>

`day` 파티션 키의 값은 ISO 형식이므로 다음 예와 같이 날짜 파티션 키에 `STRING` 대신 `DATE` 유형을 사용할 수도 있습니다.

```
PARTITIONED BY (day DATE, customer_id STRING)
```

쿼리할 때 이 전략을 사용하면 다음 예와 같이 구문 분석 또는 캐스팅하지 않고 파티션 키에 날짜 함수를 사용할 수 있습니다.

```
SELECT *
FROM my_ingested_data3
WHERE day > CURRENT_DATE - INTERVAL '7' DAY
AND customer_id = 'customer-1234'
```

**참고**  
`DATE` 유형의 파티션 키를 지정하는 경우 [사용자 지정 접두사](https://docs.aws.amazon.com/firehose/latest/dev/s3-prefixes.html) 기능을 사용하여 날짜가 ISO 형식인 Amazon S3 키를 생성하는 것으로 가정합니다. `yyyy/MM/dd/HH`의 Firehose 기본 형식을 사용하는 경우 다음 예제와 같이 해당 테이블 속성이 `date` 유형이더라도 파티션 키를 `string` 유형으로 지정해야 합니다.  

```
PARTITIONED BY ( 
  `mydate` string)
TBLPROPERTIES (
  'projection.enabled'='true', 
   ...
  'projection.mydate.type'='date',
  'storage.location.template'='s3://amzn-s3-demo-bucket/prefix/${mydate}')
```

# Amazon S3 제한 방지
<a name="performance-tuning-s3-throttling"></a>

제한은 서비스, 애플리케이션 또는 시스템 사용 속도를 제한하는 프로세스입니다. AWS에서는 제한을 사용하여 Amazon S3 서비스의 과도한 사용을 방지하고 모든 사용자에 대한 Amazon S3의 가용성과 응답성을 높일 수 있습니다. 그러나 제한 기능은 Amazon S3와의 데이터 전송 속도를 제한하므로 상호 작용이 제한되지 않도록 하는 것이 중요합니다.

[성능 조정](performance-tuning.md) 장에서 설명했듯이 최적화는 서비스 수준, 테이블 및 데이터 구조, 쿼리 작성 방법에 따라 달라질 수 있습니다.

**Topics**
+ [서비스 수준에서 제한 감소](performance-tuning-s3-throttling-reduce-throttling-at-the-service-level.md)
+ [테이블 최적화](performance-tuning-s3-throttling-optimizing-your-tables.md)
+ [쿼리 최적화](performance-tuning-s3-throttling-optimizing-queries.md)

# 서비스 수준에서 제한 감소
<a name="performance-tuning-s3-throttling-reduce-throttling-at-the-service-level"></a>

서비스 수준에서 Amazon S3 제한을 방지하려면 사용량을 모니터링하고 [서비스 할당량](https://docs.aws.amazon.com/general/latest/gr/s3.html#limits_s3)을 조정하거나 파티셔닝과 같은 특정 기술을 사용할 수 있습니다. 다음은 제한으로 이어질 수 있는 몇 가지 조건입니다.
+ **계정의 API 요청 한도 초과** - Amazon S3에는 계정 유형 및 사용량에 따른 기본 API 요청 한도가 있습니다. 단일 접두사에 대한 초당 최대 요청 수를 초과하는 경우 Amazon S3 서비스의 과부하를 방지하기 위해 요청이 제한될 수 있습니다.
+ **불충분한 데이터 파티셔닝** -데이터를 적절하게 파티셔닝하지 않고 대량의 데이터를 전송하는 경우 Amazon S3에서 요청을 제한할 수 있습니다. 파티셔닝에 대한 자세한 내용은 이 문서의 [파티셔닝 사용](performance-tuning-s3-throttling-optimizing-your-tables.md#performance-tuning-s3-throttling-use-partitioning) 섹션을 참조하세요.
+ **많은 수의 작은 객체** - 가능하면 많은 수의 작은 파일을 만들지 않습니다. Amazon S3에는 파티셔닝된 접두사 1개에 대해 초당 [5,500개의 GET 요청](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html) 한도가 있으며, Athena 쿼리는 이 한도를 공유합니다. 하나의 쿼리에서 수백만 개의 작은 객체를 스캔하는 경우 쿼리는 Amazon S3에 의해 제한될 수 있습니다.

과도한 스캔을 피하려면 AWS Glue ETL을 사용하여 파일을 주기적으로 압축하거나 테이블을 분할하고 파티션 키 필터를 추가하세요. 자세한 정보는 다음 리소스를 참조하세요.
+ [더 큰 파일을 출력하도록 AWS Glue ETL 작업을 구성하려면 어떻게 해야 합니까?](https://aws.amazon.com/premiumsupport/knowledge-center/glue-job-output-large-files/) (*AWS 지식 센터*)
+ [Reading input files in larger groups](https://docs.aws.amazon.com/glue/latest/dg/grouping-input-files.html)(*AWS Glue 개발자 안내서*)

# 테이블 최적화
<a name="performance-tuning-s3-throttling-optimizing-your-tables"></a>

제한 문제가 발생하는 경우 데이터를 구조화하는 것이 중요합니다. Amazon S3는 대량의 데이터를 처리할 수 있지만 데이터가 구조화되는 방식 때문에 때때로 제한이 발생합니다.

다음 섹션에서는 제한 문제를 방지하기 위해 Amazon S3에서 데이터를 구조화하는 방법에 대한 몇 가지 제안을 제공합니다.

## 파티셔닝 사용
<a name="performance-tuning-s3-throttling-use-partitioning"></a>

파티셔닝을 사용하면 언제든지 액세스해야 하는 데이터의 양을 제한하여 제한을 줄일 수 있습니다. 특정 열에서 데이터를 파티셔닝하면 요청을 여러 객체에서 고르게 분산하고 단일 객체에 대한 요청 수를 줄일 수 있습니다. 스캔해야 하는 데이터의 양을 줄이면 쿼리 성능이 향상되고 비용이 절감됩니다.

테이블을 생성할 때 가상 열 역할을 하는 파티션을 정의할 수 있습니다. `CREATE TABLE` 문에서 파티션이 있는 테이블을 생성하려면 `PARTITIONED BY (column_name data_type)` 절을 사용하여 데이터를 파티셔닝하는 키를 정의합니다.

쿼리에서 스캔하는 파티션을 제한하기 위해 쿼리의 `WHERE` 절에서 파티션을 조건자로 지정할 수 있습니다. 따라서 필터로 자주 사용되는 열이 파티셔닝에 적합합니다. 시간 간격에 따라 데이터를 파티셔닝하는 것이 일반적이며, 이때 여러 수준의 파티셔닝 체계가 형성될 수 있습니다.

파티셔닝에도 비용이 듭니다. 테이블에서 파티션 수를 늘리면 파티션 메타데이터를 검색하고 처리하는 데 필요한 시간도 늘어납니다. 따라서 과도하게 파티셔닝하면 보다 신중한 파티셔닝으로 얻을 수 있는 혜택이 사라질 수 있습니다. 데이터가 한 파티션 값으로 심하게 편중되고 대부분의 쿼리에서 이 값을 사용하는 경우 추가 오버헤드가 발생할 수 있습니다.

Athena에서 파티셔닝에 대한 자세한 내용은 [파티셔닝이란 무엇인가요?](ctas-partitioning-and-bucketing-what-is-partitioning.md) 섹션을 참조하세요.

## 데이터 버킷팅
<a name="performance-tuning-s3-throttling-bucket-your-data"></a>

데이터를 파티셔닝하는 또 다른 방법은 데이터를 단일 파티션 내에 버킷팅하는 것입니다. 버킷팅에서는 함께 그룹화하려는 행이 포함된 하나 이상의 열을 지정합니다. 그런 다음 해당 행을 여러 버킷에 넣습니다. 이 방식으로 읽어야 하는 버킷만 쿼리하여 스캔해야 하는 데이터 행 수를 줄일 수 있습니다.

버킷팅에 사용할 열을 선택하는 경우 카디널리티가 높고(즉, 개별 값이 많음) 균일하게 분산되었으며 데이터를 필터링하는 데 자주 사용되는 열을 선택합니다. 버킷팅에 사용하기에 좋은 열의 예로는 ID 열과 같은 기본 키가 있습니다.

Athena에서 버킷팅 사용에 대한 자세한 내용은 [버킷팅이란 무엇인가요?](ctas-partitioning-and-bucketing-what-is-bucketing.md) 섹션을 참조하세요.

## AWS Glue 파티션 인덱스 사용
<a name="performance-tuning-s3-throttling-use-aws-glue-partition-indexes"></a>

AWS Glue 파티션 인덱스를 사용하여 하나 이상의 파티션 값을 기반으로 테이블의 데이터를 구성할 수 있습니다. AWS Glue 파티션 인덱스를 사용하면 데이터 전송 횟수, 데이터 처리량, 쿼리 처리 시간을 줄일 수 있습니다.

AWS Glue 파티션 인덱스는 파티션 키 및 해당 값을 포함하여 테이블의 파티션에 대한 정보가 들어 있는 메타데이터 파일입니다. 파티션 인덱스는 Amazon S3 버킷에 저장되며 테이블에 새 파티션이 추가되면 AWS Glue에 의해 자동으로 업데이트됩니다.

AWS Glue 파티션 인덱스가 존재하면 테이블의 모든 파티션을 로드하는 대신 쿼리에서 파티션의 하위 세트를 가져오려고 합니다. 쿼리는 쿼리와 관련된 데이터의 하위 세트에서만 실행됩니다.

AWS Glue에서 테이블을 생성할 때 테이블에 정의된 파티션 키 조합에서 파티션 인덱스를 생성할 수 있습니다. 테이블에서 파티션 인덱스를 하나 이상 생성한 후에는 파티션 필터링을 활성화하는 속성을 테이블에 추가해야 합니다. 그런 다음 Athena에서 테이블을 쿼리할 수 있습니다.

AWS Glue에서 파티션 인덱스 생성에 대한 자세한 내용은 *AWS Glue 개발자 안내서*의 [Working with partition indexes in AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/partition-indexes.html)를 참조하세요. 파티션 필터링을 활성화하기 위해 테이블 속성을 추가하는 방법에 대한 자세한 내용은 [AWS Glue 파티션 인덱싱 및 필터링을 통한 쿼리 최적화](glue-best-practices-partition-index.md) 섹션을 참조하세요.

## 데이터 압축 및 파일 분할 사용
<a name="performance-tuning-s3-throttling-use-data-compression-and-file-splitting"></a>

파일이 최적 크기이거나 파일을 논리적 그룹으로 분할할 수 있는 경우 데이터 압축을 통해 쿼리 속도를 크게 높일 수 있습니다. 일반적으로 압축률이 높을수록 데이터를 압축하고 압축 해제하는 데 더 많은 CPU 사이클이 필요합니다. Athena의 경우 기본적으로 데이터를 압축하는 Apache Parquet 또는 Apache ORC를 사용하는 것이 좋습니다. Athena의 데이터 압축에 대한 자세한 내용은 [Athena에서 압축 사용](compression-formats.md) 섹션을 참조하세요.

파일을 분할하면 Athena에서 단일 파일을 읽는 작업을 여러 리더에 분산시켜 병렬 처리 성능을 높일 수 있습니다. 단일 파일을 분할할 수 없는 경우 하나의 리더만 파일을 읽고 다른 리더가 유휴 상태로 둘 수 있습니다. Apache Parquet 및 Apache ORC도 분할 가능한 파일을 지원합니다.

## 최적화된 열 기반 데이터 스토어 사용
<a name="performance-tuning-s3-throttling-use-optimized-columnar-data-stores"></a>

데이터를 열 형식으로 변환하면 Athena 쿼리 성능이 크게 향상됩니다. 열 기반 파일을 생성할 때 고려할 한 가지 최적화 기법은 파티션 키를 기준으로 데이터를 정렬하는 것입니다.

Apache Parquet 및 Apache ORC는 흔히 사용되는 오픈 소스 열 기반 데이터 스토어입니다. 기존 Amazon S3 데이터 소스를 이러한 형식 중 하나로 변환하는 방법에 대한 자세한 내용은 [열 기반 형식으로 변환](columnar-storage.md#convert-to-columnar) 섹션을 참조하세요.

### 하나의 큰 Parquet 블록 크기 또는 ORC 스트라이프 크기 사용
<a name="performance-tuning-s3-throttling-use-a-larger-parquet-block-size-or-orc-stripe-size"></a>

Parquet 및 ORC에는 최적화를 위해 조정할 수 있는 데이터 스토리지 파라미터가 있습니다. Parquet에서는 블록 크기를 최적화할 수 있습니다. ORC에서는 스트라이프 크기를 최적화할 수 있습니다. 블록이나 스트라이프가 클수록 각 블록이나 스트라이프에 저장할 수 있는 행 수가 많아집니다. 기본적으로 Parquet 블록 크기는 128MB이고 ORC 스트라이프 크기는 64MB입니다.

ORC 스트라이프가 8MB(기본값 `hive.orc.max_buffer_size`) 미만인 경우 Athena는 전체 ORC 스트라이프를 읽습니다. 스트라이프 크기가 작은 경우 Athena는 초당 입력 및 출력 작업과 열 선택성 사이에서 이와 같이 절충합니다.

열 수가 매우 많은 테이블의 경우 블록 또는 스트라이프 크기가 작으면 필요 이상으로 많은 데이터가 스캔될 수 있습니다. 이 경우에는 블록 크기가 클수록 효율적입니다.

### 복잡한 유형에 대해 ORC 사용
<a name="performance-tuning-s3-throttling-use-orc-for-complex-types"></a>

현재 Parquet에 저장된 복잡한 데이터 형식(예: `array`, `map` 또는 `struct`)의 열을 쿼리하는 경우 Athena는 지정된 열만 선택적으로 읽는 대신, 전체 데이터 행을 읽습니다. 이것은 Athena에서 알려진 문제입니다. 이 문제를 해결하려면 ORC를 사용합니다.

### 압축 알고리즘 선택
<a name="performance-tuning-s3-throttling-choose-a-compression-algorithm"></a>

사용자가 구성할 수 있는 또 다른 파라미터는 데이터 블록의 압축 알고리즘입니다. Athena에서 Parquet 및 ORC용으로 지원되는 압축 알고리즘에 대한 자세한 내용은 [Athena 압축 지원](https://docs.aws.amazon.com/athena/latest/ug/compression-formats.html)을 참조하세요.

Athena에서 열 기반 스토리지 형식 최적화에 대한 자세한 내용은 AWS 빅 데이터 블로그 게시물 [Top 10 Performance Tuning Tips for Amazon Athena](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/)의 'Optimize columnar data store generation' 섹션을 참조하세요.

## Iceberg 테이블 사용
<a name="performance-tuning-s3-throttling-use-iceberg-tables"></a>

Apache Iceberg는 Amazon S3에서 최적화된 사용을 위해 설계된 초대형 분석 데이터 세트를 위한 오픈 테이블 형식입니다. Iceberg 테이블을 사용하면 Amazon S3에서 제한을 줄이는 데 도움이 될 수 있습니다.

Iceberg 테이블은 다음과 같은 이점을 제공합니다.
+ Iceberg 테이블은 하나 이상의 열로 분할할 수 있습니다. 이렇게 하면 데이터 액세스가 최적화되고 쿼리로 스캔해야 하는 데이터의 양이 줄어듭니다.
+ Iceberg 객체 스토리지 모드는 Amazon S3에서 사용할 수 있도록 Iceberg 테이블을 최적화하므로 대량의 데이터와 많은 쿼리 워크로드를 처리할 수 있습니다.
+ 객체 스토리지 모드의 Iceberg 테이블은 확장 가능하고 내결함성이 뛰어나며 내구성이 뛰어나므로 제한을 줄이는 데 도움이 될 수 있습니다.
+ ACID 트랜잭션 지원이란, 여러 사용자가 원자 단위로 Amazon S3 객체를 추가하고 삭제할 수 있음을 의미합니다.

Apache Iceberg에 대한 자세한 내용은 [Apache Iceberg](https://iceberg.apache.org/)를 참조하세요. Athena에서 Apache Iceberg 테이블 사용에 대한 자세한 내용은 [Iceberg 테이블 사용](https://docs.aws.amazon.com/athena/latest/ug/querying-iceberg.html)을 참조하세요.

# 쿼리 최적화
<a name="performance-tuning-s3-throttling-optimizing-queries"></a>

Athena에서 SQL 쿼리를 최적화하려는 경우 이 섹션의 제안 사항을 사용합니다.

## ORDER BY 절과 함께 LIMIT 사용
<a name="performance-tuning-s3-throttling-use-limit-with-the-order-by-clause"></a>

`ORDER BY` 절은 정렬된 순서로 데이터를 반환합니다. 이를 위해 Athena에서 모든 데이터 행을 단일 워커 노드로 보낸 후 행을 정렬해야 합니다. 이러한 유형의 쿼리는 오래 실행되거나 실패할 수도 있습니다.

쿼리의 효율성을 높이려면 상위 또는 하위 *N*개 값을 확인하고 `LIMIT` 절도 사용합니다. 그러면 정렬과 제한을 단일 작업자가 아닌 개별 워커 노드로 푸시하여 정렬 비용을 크게 줄일 수 있습니다.

## JOIN 절 최적화
<a name="performance-tuning-s3-throttling-optimize-join-clauses"></a>

두 테이블을 조인하는 경우 Athena는 오른쪽에 있는 테이블을 워커 노드에 분산시킨 후 왼쪽의 테이블을 스트리밍하여 조인을 수행합니다.

따라서 조인 왼쪽에 큰 테이블을 지정하고 오른쪽에 작은 테이블을 지정합니다. 이렇게 하면 Athena는 메모리를 덜 사용하고 지연 시간을 줄이면서 쿼리를 실행합니다.

다음 사항에도 주의하세요.
+ 여러 `JOIN` 명령을 사용하는 경우 가장 큰 테이블부터 가장 작은 테이블의 순서로 지정합니다.
+ 쿼리에 필요하지 않는 한 크로스 조인을 사용하지 않습니다.

## GROUP BY 절 최적화
<a name="performance-tuning-s3-throttling-optimize-group-by-clauses"></a>

`GROUP BY` 연산자는 `GROUP BY` 열을 기반으로 워커 노드에 행을 분산시킵니다. 이러한 열은 메모리에서 참조되며 행을 모을 때 값이 비교됩니다. `GROUP BY` 열이 일치하면 값이 함께 집계됩니다. 이 프로세스의 작동 방식을 고려하면 카디널리티가 가장 높은 열부터 가장 낮은 열의 순서로 정렬하는 것이 좋습니다.

## 문자열 대신 숫자 사용
<a name="performance-tuning-s3-throttling-use-numbers-instead-of-strings"></a>

숫자는 문자열에 비해 메모리 사용량이 적고 처리 속도가 빠르므로 가능하면 문자열 대신 숫자를 사용합니다.

## 열 수 제한
<a name="performance-tuning-s3-throttling-limit-the-number-of-columns"></a>

데이터를 저장하는 데 필요한 총 메모리 양을 줄이려면 `SELECT` 문에 지정된 열 수를 제한합니다.

## LIKE 대신 정규식 사용
<a name="performance-tuning-s3-throttling-use-regular-expressions-instead-of-like"></a>

큰 문자열에서 `LIKE '%string%'`과 같은 절을 포함하는 쿼리는 컴퓨팅 집약적일 수 있습니다. 문자열 열에서 여러 값을 필터링하는 경우 대신 [regexp\$1like()](https://trino.io/docs/current/functions/regexp.html#regexp_like) 함수와 정규식을 사용합니다. 값의 긴 목록을 비교할 때 특히 유용합니다.

## LIMIT 절 사용
<a name="performance-tuning-s3-throttling-use-the-limit-clause"></a>

쿼리를 실행할 때 모든 열을 선택하는 대신 `LIMIT` 절을 사용하여 필요한 열만 반환합니다. 이렇게 하면 쿼리 실행 파이프라인을 통해 처리되는 데이터 세트의 크기가 줄어듭니다. `LIMIT` 절은 문자열 기반 열 수가 많은 테이블을 쿼리할 때 더 유용합니다. `LIMIT` 절은 쿼리에서 여러 조인 또는 집계를 수행할 때 유용합니다.

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

Athena 성능 튜닝에 대한 추가 정보는 다음 리소스를 고려하세요.
+ AWS 빅 데이터 블로그 게시물: [Top 10 performance tuning tips for Amazon Athena](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/)(Amazon Athena의 성능 튜닝을 위한 10가지 팁).
+ AWS 빅 데이터 블로그 게시물: *AWS 빅 데이터 블로그*의 [Run queries 3x faster with up to 70% cost savings on the latest Amazon Athena engine](https://aws.amazon.com/blogs/big-data/run-queries-3x-faster-with-up-to-70-cost-savings-on-the-latest-amazon-athena-engine/)(최신 Amazon Athena 엔진을 사용하면 3배 더 빠르게 쿼리를 실행하면서 최대 70%까지 비용 절감).
+ AWS 빅 데이터 블로그 게시물: [Improve federated queries with predicate pushdown in Amazon Athena](https://aws.amazon.com/blogs/big-data/improve-federated-queries-with-predicate-pushdown-in-amazon-athena/)(Amazon Athena에서 조건자 푸시다운을 사용하여 페더레이션 쿼리 개선).
+ Amazon Simple Storage Service 사용 설명서: [모범 사례 설계 패턴: Amazon S3 성능 최적화](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html).
+ [AWS 빅 데이터 블로그의 다른 Athena 게시물](https://aws.amazon.com/blogs/big-data/tag/amazon-athena/) 
+ **Amazon Athena** 태그를 사용하여 [AWS re:Post](https://repost.aws/tags/TA78iVOM7gR62_QqDe2-CmiA/amazon-athena)에 대해 질문하기.
+ [AWS 지식 센터의 Athena 주제](https://aws.amazon.com/premiumsupport/knowledge-center/#Amazon_Athena) 참조.
+ AWS Support에 문의(AWS Management Console에서 **지원**, **지원 센터** 클릭)

# Athena에서 압축 사용
<a name="compression-formats"></a>

Athena는 여러 압축 형식을 사용하는 테이블에서 데이터를 읽는 것을 비롯하여, 데이터 읽기 및 쓰기를 위한 다양한 압축 형식을 지원합니다. 예를 들어 Athena는 일부 Parquet 파일이 Snappy로 압축되고 다른 Parquet 파일이 GZIP으로 압축된 경우 Parquet 파일 형식을 사용하는 테이블의 데이터를 성공적으로 읽을 수 있습니다. ORC, 텍스트 파일, JSON 스토리지 형식에도 동일한 원칙이 적용됩니다.

## 지원되는 압축 형식
<a name="compression-support-formats"></a>

Athena는 다음 압축 형식을 지원합니다.
+ **BZIP2** – Burrows-Wheeler 알고리즘을 사용하는 형식입니다.
+ **DEFLATE** - [LZSS](https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Storer%E2%80%93Szymanski) 및 [Huffman 코딩](https://en.wikipedia.org/wiki/Huffman_coding)을 기반으로 한 압축 알고리즘입니다. [Deflate](https://en.wikipedia.org/wiki/Deflate)는 Avro 파일 형식에만 해당됩니다.
+ **GZIP** - Deflate를 기반으로 한 압축 알고리즘입니다. Athena 엔진 버전 2 및 3의 Hive 테이블과 Athena 엔진 버전 2의 Iceberg 테이블의 경우 GZIP은 Parquet 및 텍스트 파일 스토리지 형식의 파일에 대한 기본 쓰기 압축 형식입니다. `tar.gz` 형식의 파일은 지원되지 않습니다.
+ **LZ4** - Lempel-Ziv 77(LZ7) 패밀리의 이 멤버도 최대 데이터 압축이 아닌 압축 및 압축 해제 속도에 중점을 둡니다. LZ4에는 다음과 같은 프레이밍 형식이 있습니다.
  + **LZ4 Raw/Unframed** – LZ4 블록 압축 형식의 프레이밍되지 않은 표준 구현입니다. 자세한 내용은 GitHub에서 [LZ4 블록 형식 설명](https://github.com/lz4/lz4/blob/dev/doc/lz4_Block_format.md)을 참조하세요.
  + **LZ4 framed** - LZ4의 일반적인 프레이밍 구현입니다. 자세한 내용은 GitHub에서 [LZ4 프레임 형식 설명](https://github.com/lz4/lz4/blob/dev/doc/lz4_Frame_format.md)을 참조하세요.
  + **LZ4 hadoop-compatible** - LZ4의 Apache Hadoop 구현입니다. 이 구현은 LZ4 압축을 [BlockCompressorStream.java](https://github.com/apache/hadoop/blob/f67237cbe7bc48a1b9088e990800b37529f1db2a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/compress/BlockCompressorStream.java) 클래스로 래핑합니다.
+ **LZO** - 최대 데이터 압축이 아닌 높은 압축 및 압축 해제 속도에 중점을 둔 Lempel–Ziv–Oberhumer 알고리즘을 사용하는 형식입니다. LZO에는 두 가지 구현이 있습니다.
  + **Standard LZO** - 자세한 내용은 Oberhumer 웹 사이트에서 LZO [요약](http://www.oberhumer.com/opensource/lzo/#abstract)을 참조하세요.
  + **LZO hadoop-compatible** - 이 구현은 LZO 알고리즘을 [BlockCompressorStream.java](https://github.com/apache/hadoop/blob/f67237cbe7bc48a1b9088e990800b37529f1db2a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/compress/BlockCompressorStream.java) 클래스로 래핑합니다.
+ **SNAPPY** – Lempel-Ziv 77 (LZ7) 패밀리의 일부인 압축 알고리즘입니다. Snappy는 데이터를 최대한 압축하는 것이 아니라, 높은 압축 및 압축 해제 속도에 중점을 둡니다.
+ **ZLIB** - Deflate를 기반으로 한 ZLIB는 ORC 데이터 스토리지 형식의 파일에 대한 기본 쓰기 압축 형식입니다. 자세한 내용은 GitHub에서 [zlib](https://github.com/madler/zlib) 페이지를 참조하세요.
+  **ZSTD** - [Zstandard 실시간 데이터 압축 알고리즘](http://facebook.github.io/zstd/)은 높은 압축비를 제공하는 빠른 압축 알고리즘입니다. Zstandard(ZSTD) 라이브러리는 BSD 라이선스를 사용하는 오픈 소스 소프트웨어로 제공됩니다. ZSTD는 Iceberg 테이블의 기본 압축입니다. ZSTD 압축 데이터를 작성할 때 Athena는 기본적으로 ZSTD 압축 수준 3을 사용합니다. Athena의 ZSTD 압축 수준 사용에 대한 자세한 내용은 [ZSTD 압축 수준 사용](compression-support-zstd-levels.md) 섹션을 참조하세요.

**참고**  
Athena는 LZ4 또는 LZO 형식으로 압축된 Parquet 파일 쓰기를 지원하지 않습니다. 이러한 압축 형식에 대한 읽기는 계속 지원됩니다.

## 압축 형식 지정
<a name="compression-support-specifying-compression-formats"></a>

CREATE TABLE 또는 CTAS 문을 작성할 때, Athena가 해당 테이블에 쓸 경우 사용할 압축 유형을 지정하는 압축 속성을 지정할 수 있습니다.
+ CTAS의 경우 [CTAS 테이블 속성](create-table-as.md#ctas-table-properties) 섹션을 참조하세요. 예시는 [CTAS 쿼리 예제](ctas-examples.md) 섹션을 참조하세요.
+ CREATE TABLE의 경우 [ALTER TABLE SET TBLPROPERTIES](alter-table-set-tblproperties.md)에서 압축 테이블 속성 목록을 참조하세요.

## 압축 안 함 지정
<a name="compression-support-specifying-no-compression"></a>

CREATE TABLE 문은 압축되지 않은 파일을 지원합니다. 압축되지 않은 파일을 작성하려면 다음 구문을 사용합니다.
+ 테이블 만들기(텍스트 파일 또는 JSON) —`TBLPROPERTIES`를 지정합니다.`write.compression = NONE`.
+ 테이블 만들기(Parquet) —`parquet.compression = UNCOMPRESSED`에서 `TBLPROPERTIES`를 지정합니다.
+ 테이블 생성 (ORC) — `orc.compress = NONE`에서 `TBLPROPERTIES`를 지정합니다.

## 참고 및 리소스
<a name="compression-support-notes-and-resources"></a>
+ 현재 `.GZ` 또는 `.BZIP2`와 같은 대문자 파일 확장명은 Athena에서 인식되지 않습니다. 파일 확장명이 대문자인 데이터 세트을 사용하지 않거나 데이터 파일 확장명의 이름을 소문자로 바꿉니다.
+ CSV, TSV 및 JSON 형식 데이터의 경우 Athena는 파일 확장명에서 압축 형식을 결정합니다. 파일 확장자가 없는 경우 Athena는 데이터를 압축되지 않은 일반 텍스트로 처리합니다. 데이터가 압축된 경우 파일 이름에 `gz`와 같은 압축 확장명이 포함되어 있는지 확인하세요.
+ ZIP 파일 형식은 지원되지 않습니다.
+ Athena에서 querying Amazon Data Firehose 로그를 쿼리하는 경우, 지원되는 형식에는 GZIP 압축 또는 SNAPPY 압축을 사용하는 ORC 파일이 포함됩니다.
+ 압축 사용에 대한 자세한 내용은 AWS 빅 데이터 블로그 게시물 [Top 10 performance tuning tips for Amazon Athena](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/)(Amazon Athena의 성능 튜닝을 위한 10가지 팁)의 섹션 3(“Compress and split files(파일 압축 및 분할)”)을 참조하세요.

**Topics**
+ [압축 형식 지정](#compression-support-specifying-compression-formats)
+ [압축 안 함 지정](#compression-support-specifying-no-compression)
+ [참고 및 리소스](#compression-support-notes-and-resources)
+ [Hive 테이블 압축](compression-support-hive.md)
+ [Iceberg 테이블 최적화](compression-support-iceberg.md)
+ [ZSTD 압축 수준](compression-support-zstd-levels.md)

# Hive 테이블 압축 사용
<a name="compression-support-hive"></a>

Athena의 Hive 테이블 압축 옵션은 엔진 버전과 파일 형식에 따라 다릅니다.

## Athena 엔진 버전 3의 Hive 압축 지원
<a name="compression-support-hive-v3"></a>

다음 표에는 Apache Hive의 스토리지 파일 형식에 대한 Athena 엔진 버전 3의 압축 형식 지원이 요약되어 있습니다. 텍스트 파일 형식에는 TSV, CSV, JSON 및 텍스트용 사용자 정의 SerDes가 포함됩니다. 셀의 “예” 또는 “아니요”는 별도로 명시된 경우를 제외하고 읽기 작업과 쓰기 작업에 동일하게 적용됩니다. 이 테이블에서는 CREATE TABLE, CTAS 및 INSERT INTO를 쓰기 작업으로 간주합니다. Athena의 ZSTD 압축 수준 사용에 대한 자세한 내용은 [ZSTD 압축 수준 사용](compression-support-zstd-levels.md) 섹션을 참조하세요.


****  

|  | Avro | Ion | ORC | PARQUET | 텍스트 파일 | 
| --- | --- | --- | --- | --- | --- | 
| bzip2 | 예 | 예 | 아니요 | 아니요 | 예 | 
| DEFLATE | 예 | 아니요 | 아니요 | 아니요 | 아니요 | 
| GZIP | 아니요 | 예 | 아니요 | 예 | 예 | 
| LZ4 | 아니요 | 예 | 예 |  쓰기 - 아니요 읽기 - 예  | 예 | 
| LZO | 아니요 |  쓰기 - 아니요 읽기 - 예  | 아니요 |  쓰기 - 아니요 읽기 - 예  |  쓰기 - 아니요 읽기 - 예  | 
| Snappy | 예 | 예 | 예 | 예 | 예 | 
| ZLIB | 아니요 | 아니요 | 예 | 아니요 | 아니요 | 
| ZSTD | 예 | 예 | 예 | 예 | 예 | 
| NONE | 예 | 예 | 예 | 예 | 예 | 

# Iceberg 테이블 압축 사용
<a name="compression-support-iceberg"></a>

Athena의 Iceberg 테이블 압축 옵션은 엔진 버전과 파일 형식에 따라 다릅니다.

## Athena 엔진 버전 3의 Iceberg 압축 지원
<a name="compression-support-iceberg-v3"></a>

다음 표에는 Apache Iceberg의 스토리지 파일 형식에 대한 Athena 엔진 버전 3의 압축 형식 지원이 요약되어 있습니다. 셀의 “예” 또는 “아니요”는 별도로 명시된 경우를 제외하고 읽기 작업과 쓰기 작업에 동일하게 적용됩니다. 이 테이블에서는 CREATE TABLE, CTAS 및 INSERT INTO를 쓰기 작업으로 간주합니다. Athena 엔진 버전 3에서 Iceberg에 대한 기본 스토리지 형식은 Parquet입니다. Athena 엔진 버전 3에서 Iceberg에 대한 기본 압축 형식은 ZSTD입니다. Athena의 ZSTD 압축 수준 사용에 대한 자세한 내용은 [ZSTD 압축 수준 사용](compression-support-zstd-levels.md) 섹션을 참조하세요.


****  

|  | Avro | ORC | Parquet(기본값) | 
| --- | --- | --- | --- | 
| bzip2 | 아니요 | 아니요 | 아니요 | 
| GZIP | 예 | 아니요 | 예 | 
| LZ4 | 아니요 | 예 | 아니요 | 
| Snappy | 예 | 예 | 예 | 
| ZLIB | 아니요 | 예 | 아니요 | 
| ZSTD | 예 | 예 | 예(기본값) | 
| NONE | 예(None 또는 Deflate 지정) | 예 | 예(None 또는 Uncompressed 지정) | 

# ZSTD 압축 수준 사용
<a name="compression-support-zstd-levels"></a>

[Zstandard 실시간 데이터 압축 알고리즘](http://facebook.github.io/zstd/)은 높은 압축비를 제공하는 빠른 압축 알고리즘입니다. Zstandard(ZSTD) 라이브러리는 오픈 소스 소프트웨어이며 BSD 라이선스를 사용합니다. Athena는 ZSTD 압축 ORC, Parquet 및 텍스트 파일 데이터 읽기 및 쓰기를 지원합니다.

ZSTD 압축 수준을 사용하여 요구 사항에 따라 압축률과 속도를 조정할 수 있습니다. ZSTD 라이브러리는 1\$122의 압축 수준을 지원합니다. Athena는 기본적으로 ZSTD 압축 수준 3을 사용합니다.

압축 수준은 압축 속도와 달성된 압축량 간의 세분화된 균형을 제공합니다. 압축 수준이 낮을수록 속도는 빨라지지만 파일 크기는 커집니다. 예를 들어 속도가 가장 중요한 경우 수준 1을 사용하고 크기가 가장 중요한 경우 수준 22를 사용할 수 있습니다. 수준 3이 많은 사용 사례에 적합하며 기본값입니다. 수준 20부터는 더 많은 메모리가 필요하므로 주의하여 사용하세요. ZSTD 라이브러리는 또한 압축 속도와 비율의 범위를 확장하는 네거티브 압축 수준을 제공합니다. 자세한 내용은 [Zstandard Compression RFC](https://datatracker.ietf.org/doc/html/rfc8478)(Zstandard 압축 RFC)를 참조하세요.

많은 압축 수준은 미세 조정을 위한 상당한 기회를 제공합니다. 그러나 압축 수준을 결정할 때 데이터를 측정하고 장단점을 고려해야 합니다. 압축 속도와 압축된 데이터 크기 간의 적절한 균형을 위해 기본 수준 3 또는 수준 6\$19를 사용하는 것이 좋습니다. 크기가 가장 중요하고 압축 속도가 중요하지 않은 경우에는 수준 20 이상을 예약하세요.

## 고려 사항 및 제한 사항
<a name="compression-support-zstd-levels-considerations-and-limitations"></a>

Athena에서 ZSTD 압축 수준을 사용할 때 다음 사항을 고려하세요.
+ ZSTD `compression_level` 속성은 Athena 엔진 버전 3에서만 지원됩니다.
+ ZSTD `compression_level` 속성은 `ALTER TABLE`, `CREATE TABLE`, `CREATE TABLE AS`(CTAS) 및 `UNLOAD` 문에 지원됩니다.
+ `compression_level` 속성은 선택 사항입니다.
+ `compression_level` 속성은 ZSTD 압축에만 지원됩니다.
+ 가능한 압축 수준은 1\$122입니다.
+ 기본 압축 수준은 3입니다.

Athena에서 Apache Hive ZSTD 압축 지원에 대한 자세한 내용은 [Hive 테이블 압축 사용](compression-support-hive.md) 섹션을 참조하세요. Athena에서 Apache Iceberg ZSTD 압축 지원에 대한 자세한 내용은 [Iceberg 테이블 압축 사용](compression-support-iceberg.md) 섹션을 참조하세요.

## ZSTD 압축 수준 지정
<a name="compression-support-zstd-levels-specifying"></a>

`ALTER TABLE`, `CREATE TABLE`, `CREATE TABLE AS` 및 `UNLOAD` 문에 ZSTD 압축 수준을 지정하려면 `compression_level` 속성을 사용합니다. ZSTD 압축 자체를 지정하려면 문의 구문에서 사용하는 개별 압축 속성을 사용해야 합니다.

### ALTER TABLE SET TBLPROPERTIES
<a name="compression-support-zstd-levels-alter-table"></a>

[ALTER TABLE SET TBLPROPERTIES](alter-table-set-tblproperties.md) 문 `SET TBLPROPERTIES` 절에서 `'write.compression' = ' ZSTD'` 또는 `'parquet.compression' = 'ZSTD'`를 사용하여 ZSTD 압축을 지정합니다. 그런 다음 `compression_level` 속성을 사용하여 1에서 22 사이의 값을 지정합니다(예: '`compression_level' = '5'`). 압축 수준 속성을 지정하지 않으면 압축 수준은 기본적으로 3으로 설정됩니다.

#### 예제
<a name="compression-support-zstd-levels-alter-table-example"></a>

다음 예제에서는 ZSTD 압축 및 ZSTD 압축 수준 4와 함께 Parquet 파일 형식을 사용하도록 테이블 `existing_table`을 수정합니다. `TBLPROPERTIES`에서 압축 수준 값은 정수가 아닌 문자열로 입력해야 합니다. 따라서 작은 따옴표 또는 큰 따옴표로 묶어야 합니다.

```
ALTER TABLE existing_table 
SET TBLPROPERTIES ('parquet.compression' = 'ZSTD', 'compression_level' = '4')
```

### CREATE TABLE
<a name="compression-support-zstd-levels-create-table"></a>

[CREATE TABLE](create-table.md) 문 `TBLPROPERTIES` 절에서 '`write.compression' = 'ZSTD'` 또는 `'parquet.compression' = 'ZSTD'`를 지정한 다음 `compression_level = compression_level`을 사용하고 1에서 22 사이의 값을 문자열로 지정합니다. `compression_level` 속성이 지정되지 않은 경우 기본 압축 수준은 3입니다.

#### 예제
<a name="compression-support-zstd-levels-create-table-example"></a>

다음 예제에서는 ZSTD 압축과 ZSTD 압축 수준 4를 사용하여 Parquet 파일 형식으로 테이블을 생성합니다.

```
CREATE EXTERNAL TABLE new_table ( 
  `col0` string COMMENT '', 
  `col1` string COMMENT '' 
) 
STORED AS PARQUET 
LOCATION 's3://amzn-s3-demo-bucket/' 
TBLPROPERTIES ('write.compression' = 'ZSTD', 'compression_level' = '4')
```

### CREATE TABLE AS (CTAS)
<a name="compression-support-zstd-levels-ctas"></a>

[CREATE TABLE AS](create-table-as.md) 문 `WITH` 절에서 `write_compression = 'ZSTD'` 또는 `parquet_compression = 'ZSTD'`를 지정한 다음 `compression_level = compression_level`을 사용하고 1에서 22 사이의 값을 문자열로 지정합니다. `compression_level` 속성이 지정되지 않은 경우 기본 압축 수준은 3입니다.

#### 예제
<a name="compression-support-zstd-levels-ctas-example"></a>

다음 CTAS 예제에서는 ZSTD 압축과 압축 수준 4를 사용하여 Parquet를 파일 형식으로 지정합니다. 단, `WITH` 절에서는 압축 수준 값을 문자열이 아닌 정수로 지정해야 합니다.

```
CREATE TABLE new_table  
WITH ( format = 'PARQUET', write_compression = 'ZSTD', compression_level = 4)  
AS SELECT * FROM old_table
```

### UNLOAD
<a name="compression-support-zstd-levels-unload"></a>

[UNLOAD](unload.md) 문 `WITH` 절에서 `compression = 'ZSTD'`를 지정한 다음 `compression_level = compression_level`을 사용하고 1에서 22 사이의 값을 문자열로 지정합니다. `compression_level` 속성이 지정되지 않은 경우 기본 압축 수준은 3입니다.

#### 예제
<a name="compression-support-zstd-levels-unload-example"></a>

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

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

# Athena 리소스 태깅
<a name="tags"></a>

각 태그는 사용자가 정의하는 키와 값으로 구성됩니다. Athena 리소스에 태그를 지정할 때 사용자 지정 메타데이터를 할당합니다. 태그를 사용하여 AWS 리소스를 용도, 소유자, 환경 등으로 다양하게 분류할 수 있습니다. Athena에서 작업 그룹, 데이터 카탈로그 및 용량 예약과 같은 리소스에 태그를 지정할 수 있습니다. 예를 들어, 계정의 작업 그룹에 대해 작업 그룹 소유자를 추적하거나 해당 용도별로 작업 그룹을 식별할 수 있는 태그를 설정할 수 있습니다. Billing and Cost Management 콘솔에서 비용 할당 태그로 태그를 활성화하면 쿼리 실행과 관련된 비용이 해당 비용 할당 태그와 함께 Cost and Usage Report에 나타납니다. AWS [태그 지정 모범 사례](https://docs.aws.amazon.com/whitepapers/latest/tagging-best-practices/tagging-best-practices.html)를 사용하여 각 조직의 요구 사항에 맞게 일관된 태그 세트를 생성하는 것이 좋습니다.

Athena 콘솔이나 API 작업을 사용하여 태그 작업을 수행할 수 있습니다.

**Topics**
+ [태그 기본 사항](#tag-basics)
+ [태그 제한 사항](#tag-restrictions)
+ [작업 그룹에 대한 태그 작업](tags-console.md)
+ [API 및 AWS CLI 태그 작업 사용](tags-operations.md)
+ [태그 기반 IAM 액세스 제어 정책 사용](tags-access-control.md)

## 태그 기본 사항
<a name="tag-basics"></a>

태그는 Athena 리소스에 할당하는 레이블입니다. 각 태그는 사용자가 정의하는 키와 선택적 값으로 구성됩니다.

태그를 사용하면 다양한 방식으로 AWS 리소스를 분류할 수 있습니다. 예를 들어 계정의 작업 그룹에 대해 각 작업 그룹 소유자나 용도를 추적할 수 있는 태그를 정의할 수 있습니다.

새로운 Athena 작업 그룹 또는 데이터 카탈로그를 생성할 때 태그를 추가할 수 있으며, 해당 작업 그룹 또는 데이터 카탈로그에서 태그를 추가, 편집 또는 제거할 수 있습니다. 태그는 콘솔에서 편집할 수 있습니다. API 작업을 사용하여 태그를 편집하려면 기존 태그를 제거하고 새 태그를 추가합니다. 리소스를 삭제하면 리소스 태그도 삭제됩니다.

Athena는 리소스에 태그를 자동으로 할당하지 않습니다. 태그 키와 값을 편집할 수 있으며 언제든지 리소스에서 태그를 제거할 수 있습니다. 태그의 값을 빈 문자열로 설정할 수 있지만 태그의 값을 Null로 설정할 수는 없습니다. 중복된 태그 키를 동일한 리소스에 추가하지 마세요. 이렇게 할 경우 Athena에서 오류 메시지가 표시됩니다. 기존 태그 키를 사용하여 리소스에 태그를 지정하는 데 **TagResource** 작업을 사용하는 경우 새 태그 값이 기존 값을 덮어씁니다.

IAM에서는 Amazon Web Services 계정에서 태그를 생성, 편집, 제거하거나 태그 목록을 조회할 수 있는 권한을 가진 사용자를 제어할 수 있습니다. 자세한 내용은 [태그 기반 IAM 액세스 제어 정책 사용](tags-access-control.md) 단원을 참조하세요.

Amazon Athena 태그 작업의 전체 목록은 [Amazon Athena API 참조](https://docs.aws.amazon.com/athena/latest/APIReference/)의 API 작업 이름을 참조하세요.

청구에 태그를 사용할 수 있습니다. 자세한 내용은 *AWS 결제 및 비용 관리 사용 설명서*의 [결제 목적으로 태그 사용](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/custom-tags.html)을 참조하세요.

자세한 내용은 [태그 제한 사항](#tag-restrictions) 단원을 참조하세요.

## 태그 제한 사항
<a name="tag-restrictions"></a>

태그에는 다음 제한 사항이 있습니다.
+ Athena에서는 작업 그룹, 데이터 카탈로그 및 용량 예약에 태그를 지정할 수 있습니다. 쿼리에는 태그를 지정할 수 없습니다.
+ 리소스당 최대 태그 수는 50개입니다. 한도를 유지하려면 사용하지 않는 태그를 검토하여 삭제하세요.
+ 각 리소스에 대해 각 태그 키는 고유하며 하나의 값만 가질 수 있습니다. 동일한 리소스에 중복된 태그 키를 동시에 추가하지 마세요. 이렇게 할 경우 Athena에서 오류 메시지가 표시됩니다. 개별 `TagResource` 작업의 기존 태그 키를 사용하여 리소스에 태그를 지정할 경우 새 태그 값이 기존 값을 덮어씁니다.
+ 태그 키 길이는 UTF-8 형식의 1-128자의 유니코드 문자입니다.
+ 태그 값 길이는 UTF-8 형식의 0-256자의 유니코드 문자입니다.

  태그 추가, 편집, 제거, 목록 조회 등과 같은 태그 지정 작업을 하려면 작업 그룹 리소스의 ARN을 지정해야 합니다.
+ Athena에서는 UTF-8 형식의 문자, 숫자, 공백 및 \$1 - = . \$1 : / @ 문자를 사용할 수 있습니다.
+ 태그 키와 값은 대/소문자를 구분합니다.
+ 태그 키의 `"aws:"` 접두사는 AWS용으로 예약되어 있습니다. 이 접두사가 지정된 태그 키는 편집하거나 삭제할 수 없습니다. 이 접두사가 지정된 태그는 리소스당 태그 수 제한에 포함되지 않습니다.
+ 할당한 태그는 해당 Amazon Web Services 계정에서만 사용할 수 있습니다.

# 작업 그룹에 대한 태그 작업
<a name="tags-console"></a>

Athena 콘솔을 사용하여 해당 계정의 각 작업 그룹에서 사용 중인 태그를 볼 수 있습니다. 작업 그룹별로만 태그를 볼 수 있습니다. 또한 Athena 콘솔을 사용하여 한 번에 하나의 작업 그룹에서 태그를 적용, 편집, 제거할 수 있습니다.

작성한 태그를 사용하여 작업 그룹을 검색할 수 있습니다.

**Topics**
+ [개별 작업 그룹에 대한 태그 표시](#tags-display)
+ [개별 작업 그룹에 대한 태그 추가 및 삭제](#tags-add-delete)

## 개별 작업 그룹에 대한 태그 표시
<a name="tags-display"></a>

**Athena 콘솔에서 개별 작업 그룹의 태그 표시**

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 콘솔 탐색 창이 표시되지 않으면 왼쪽의 확장 메뉴를 선택합니다.  
![\[확장 메뉴를 선택합니다.\]](http://docs.aws.amazon.com/ko_kr/athena/latest/ug/images/nav-pane-expansion.png)

1. 탐색 메뉴에서 **작업 그룹(Workgroups)**을 선택한 다음 원하는 작업 그룹을 선택합니다.

1. 다음 중 하나를 수행하세요.
   + **태그** 탭을 선택합니다. 태그 목록이 긴 경우 검색 상자를 사용합니다.
   + **편집(Edit)**을 선택하고 **태그(Tags)** 섹션까지 아래로 스크롤합니다.

## 개별 작업 그룹에 대한 태그 추가 및 삭제
<a name="tags-add-delete"></a>

**작업 그룹** 탭에서 개별 작업 그룹에 대한 태그를 직접 관리할 수 있습니다.

**참고**  
사용자가 콘솔에서 작업 그룹을 생성할 때 태그를 추가하도록 하거나 **CreateWorkGroup** 작업을 사용할 때 태그를 전달하도록 하려면 **TagResource** 및 **CreateWorkGroup** 작업에 대한 IAM 권한을 해당 사용자에게 부여해야 합니다.

**작업 그룹을 새로 생성할 때 태그 추가**

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 탐색 메뉴에서 **작업 그룹(Workgroups)**을 클릭합니다.

1. **작업 그룹 생성(Create workgroup)**을 선택하고 필요에 따라 값을 입력합니다. 자세한 단계는 [작업 그룹 만들기](creating-workgroups.md) 섹션을 참조하세요.

1. **태그(Tags)** 섹션에서 키와 값을 지정하여 태그를 하나 이상 추가합니다. 동일한 작업 그룹에 중복된 태그 키를 동시에 추가하지 마세요. 이렇게 할 경우 Athena에서 오류 메시지가 표시됩니다. 자세한 내용은 [태그 제한 사항](tags.md#tag-restrictions) 단원을 참조하세요.

1. 완료했으면 **작업 그룹 생성(Create workgroup)**을 선택합니다.

**기존 작업 그룹에 대해 태그를 추가하거나 편집하려면**

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 탐색 창에서 **작업 그룹(Workgroups)**을 선택합니다.

1. 수정할 작업 그룹을 선택합니다.

1. 다음 중 하나를 수행하세요.
   + **태그**(Tags) 탭을 선택한 후 **태그 관리**(Manage tags)를 선택합니다.
   + **편집(Edit)**을 선택하고 **태그(Tags)** 섹션까지 아래로 스크롤합니다.

1. 각 태그에 대한 키 및 값을 지정합니다. 자세한 내용은 [태그 제한 사항](tags.md#tag-restrictions) 섹션을 참조하세요.

1. **저장**을 선택합니다.

**개별 작업 그룹에서 태그를 삭제하려면**

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 탐색 창에서 **작업 그룹(Workgroups)**을 선택합니다.

1. 수정할 작업 그룹을 선택합니다.

1. 다음 중 하나를 수행하세요.
   + **태그**(Tags) 탭을 선택한 후 **태그 관리**(Manage tags)를 선택합니다.
   + **편집(Edit)**을 선택하고 **태그(Tags)** 섹션까지 아래로 스크롤합니다.

1. 태그 목록에서 삭제하려는 태그에 대해 **제거(Remove)**를 선택한 후 **저장(Save)**을 선택합니다.

# API 및 AWS CLI 태그 작업 사용
<a name="tags-operations"></a>

다음 태그 작업을 사용하여 리소스에서 태그를 추가, 제거 또는 나열할 수 있습니다.


****  

| API | CLI | 작업 설명 | 
| --- | --- | --- | 
| TagResource | tag-resource | 지정된 ARN이 있는 리소스에 태그를 한 개 이상 추가하거나 덮어씁니다. | 
| UntagResource | untag-resource | 지정된 ARN이 있는 리소스에서 태그를 한 개 이상 삭제합니다. | 
| ListTagsForResource | list‑tags‑for‑resource | 지정된 ARN이 있는 리소스의 태그를 한 개 이상 나열합니다. | 

**리소스를 생성할 때 태그 추가**  
작업 그룹 또는 데이터 카탈로그를 생성할 때 태그를 추가하려면 `CreateWorkGroup` 또는 `CreateDataCatalog` API 작업이나 AWS CLI `create-work-group` 또는 `create-data-catalog` 명령과 함께 `tags` 파라미터를 사용합니다.

## API 작업을 사용하여 태그 관리
<a name="tags-operations-examples-java"></a>

이 섹션의 예제에서는 태그 API 작업을 사용하여 작업 그룹 및 데이터 카탈로그의 태그를 관리하는 방법을 보여줍니다. 예제는 Java 프로그래밍 언어로 작성되어 있습니다.

### 예 - TagResource
<a name="tags-operations-examples-java-tag-resource"></a>

다음 예제에서는 작업 그룹 `workgroupA`에 두 개의 태그를 추가합니다.

```
List<Tag> tags = new ArrayList<>();
tags.add(new Tag().withKey("tagKey1").withValue("tagValue1"));
tags.add(new Tag().withKey("tagKey2").withValue("tagValue2"));

TagResourceRequest request = new TagResourceRequest()
    .withResourceARN("arn:aws:athena:us-east-1:123456789012:workgroup/workgroupA")
    .withTags(tags);

client.tagResource(request);
```

다음 예제에서는 데이터 카탈로그 `datacatalogA`에 두 개의 태그를 추가합니다.

```
List<Tag> tags = new ArrayList<>();
tags.add(new Tag().withKey("tagKey1").withValue("tagValue1"));
tags.add(new Tag().withKey("tagKey2").withValue("tagValue2"));

TagResourceRequest request = new TagResourceRequest()
    .withResourceARN("arn:aws:athena:us-east-1:123456789012:datacatalog/datacatalogA")
    .withTags(tags);

client.tagResource(request);
```

**참고**  
중복된 태그 키를 동일한 리소스에 추가하지 마세요. 이렇게 할 경우 Athena에서 오류 메시지가 표시됩니다. 개별 `TagResource` 작업의 기존 태그 키를 사용하여 리소스에 태그를 지정할 경우 새 태그 값이 기존 값을 덮어씁니다.

### 예 - UntagResource
<a name="tags-operations-examples-java-untag-resource"></a>

다음 예제에서는 작업 그룹 `workgroupA`에서 `tagKey2`를 제거합니다.

```
List<String> tagKeys = new ArrayList<>();
tagKeys.add("tagKey2");

UntagResourceRequest request = new UntagResourceRequest()
    .withResourceARN("arn:aws:athena:us-east-1:123456789012:workgroup/workgroupA")
    .withTagKeys(tagKeys);

client.untagResource(request);
```

다음 예제에서는 데이터 카탈로그 `datacatalogA`에서 `tagKey2`를 제거합니다.

```
List<String> tagKeys = new ArrayList<>();
tagKeys.add("tagKey2");

UntagResourceRequest request = new UntagResourceRequest()
    .withResourceARN("arn:aws:athena:us-east-1:123456789012:datacatalog/datacatalogA")
    .withTagKeys(tagKeys);

client.untagResource(request);
```

### 예 - ListTagsForResource
<a name="tags-operations-examples-java-list-tags-for-resource"></a>

다음 예제에서는 작업 그룹 `workgroupA`에 대한 태그를 나열합니다.

```
ListTagsForResourceRequest request = new ListTagsForResourceRequest()
    .withResourceARN("arn:aws:athena:us-east-1:123456789012:workgroup/workgroupA");

ListTagsForResourceResult result = client.listTagsForResource(request);

List<Tag> resultTags = result.getTags();
```

다음 예제에서는 데이터 카탈로그 `datacatalogA`에 대한 태그를 나열합니다.

```
ListTagsForResourceRequest request = new ListTagsForResourceRequest()
    .withResourceARN("arn:aws:athena:us-east-1:123456789012:datacatalog/datacatalogA");

ListTagsForResourceResult result = client.listTagsForResource(request);

List<Tag> resultTags = result.getTags();
```

## AWS CLI를 사용하여 태그 관리
<a name="tags-operations-examples-cli"></a>

다음 예제는 AWS CLI를 사용하여 데이터 카탈로그에서 태그를 생성하고 관리하는 방법을 보여줍니다.

### 리소스에 태그 추가: tag-resource
<a name="tags-operations-examples-cli-tag-resource"></a>

`tag-resource` 명령은 지정된 리소스에 태그를 한 개 이상 추가합니다.

**구문**  
`aws athena tag-resource --resource-arn arn:aws:athena:region:account_id:datacatalog/catalog_name --tags Key=string,Value=string Key=string,Value=string`

`--resource-arn` 파라미터는 태그가 추가되는 리소스를 지정합니다. `--tags` 파라미터는 리소스에 태그로 추가할 공백으로 구분된 키-값 페어의 목록을 지정합니다.

**Example**  
다음 예제에서는 데이터 카탈로그 `mydatacatalog`에 태그를 추가합니다.  

```
aws athena tag-resource --resource-arn arn:aws:athena:us-east-1:111122223333:datacatalog/mydatacatalog --tags Key=Color,Value=Orange Key=Time,Value=Now
```
결과를 표시하려면 `list-tags-for-resource` 명령을 사용합니다.  
`create-data-catalog` 명령 사용 시 태그 추가에 대한 자세한 내용은 [카탈로그 등록: Create-data-catalog](datastores-hive-cli.md#datastores-hive-cli-registering-a-catalog) 단원을 참조하세요.

### 리소스에 대한 태그 나열: list-tags-for-resource
<a name="tags-operations-examples-cli-list-tags-for-resource"></a>

`list-tags-for-resource` 명령은 지정된 리소스에 대한 태그를 나열합니다.

**구문**  
`aws athena list-tags-for-resource --resource-arn arn:aws:athena:region:account_id:datacatalog/catalog_name`

`--resource-arn` 파라미터는 태그를 나열하기 위한 리소스를 지정합니다.

다음 예제에서는 데이터 카탈로그 `mydatacatalog`에 대한 태그를 나열합니다.

```
aws athena list-tags-for-resource --resource-arn arn:aws:athena:us-east-1:111122223333:datacatalog/mydatacatalog
```

다음 샘플 결과는 JSON 형식입니다.

```
{
    "Tags": [
        {
            "Key": "Time",
            "Value": "Now"
        },
        {
            "Key": "Color",
            "Value": "Orange"
        }
    ]
}
```

### 리소스에서 태그 제거: untag-resource
<a name="tags-operations-examples-cli-untag-resource"></a>

`untag-resource` 명령은 지정된 리소스에서 지정된 태그 키 및 관련된 값을 제거합니다.

**구문**  
`aws athena untag-resource --resource-arn arn:aws:athena:region:account_id:datacatalog/catalog_name --tag-keys key_name [key_name ...]` 

`--resource-arn` 파라미터는 태그를 제거하기 위한 리소스를 지정합니다. `--tag-keys` 파라미터는 공백으로 구분된 키 이름 목록을 사용합니다. `untag-resource` 명령은 지정된 각 키 이름에서 키 및 해당 값을 모두 제거합니다.

다음 예제에서는 `Color` 및 `Time` 키와 해당 값을 `mydatacatalog` 카탈로그 리소스에서 제거합니다.

```
aws athena untag-resource --resource-arn arn:aws:athena:us-east-1:111122223333:datacatalog/mydatacatalog --tag-keys Color Time
```

# 태그 기반 IAM 액세스 제어 정책 사용
<a name="tags-access-control"></a>

태그를 사용하면 `Condition` 블록이 포함된 IAM 정책을 작성하여 태그를 기반으로 리소스에 대한 액세스를 제어할 수 있습니다. 이 섹션에는 작업 그룹 및 데이터 카탈로그 리소스에 대한 태그 정책 예제가 포함되어 있습니다.

## 작업 그룹에 대한 태그 정책 예제
<a name="tag-policy-examples-workgroups"></a>

### 예 - 기본 태깅 정책
<a name="tag-policy-examples-workgroups-basic"></a>

다음 IAM 정책은 `workgroupA`라는 작업 그룹에 대해 쿼리를 실행하고 태그 작업을 할 수 있도록 허용합니다.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
       {
            "Effect": "Allow",
            "Action": [
                "athena:ListWorkGroups",
                "athena:ListEngineVersions",
                "athena:ListDataCatalogs",
                "athena:ListDatabases",
                "athena:GetDatabase",
                "athena:ListTableMetadata",
                "athena:GetTableMetadata"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "athena:GetWorkGroup",
                "athena:TagResource",
                "athena:UntagResource",
                "athena:ListTagsForResource",
                "athena:StartQueryExecution",
                "athena:GetQueryExecution",
                "athena:BatchGetQueryExecution",
                "athena:ListQueryExecutions",
                "athena:StopQueryExecution",
                "athena:GetQueryResults",
                "athena:GetQueryResultsStream",
                "athena:CreateNamedQuery",
                "athena:GetNamedQuery",
                "athena:BatchGetNamedQuery",
                "athena:ListNamedQueries",
                "athena:DeleteNamedQuery",
                "athena:CreatePreparedStatement",
                "athena:GetPreparedStatement",
                "athena:ListPreparedStatements",
                "athena:UpdatePreparedStatement",
                "athena:DeletePreparedStatement"
            ],
            "Resource": "arn:aws:athena:us-east-1:123456789012:workgroup/workgroupA"
        }
    ]
}
```

------

### 예 - 태그 키와 태그 값 페어를 기반으로 작업 그룹에서 작업을 거부하는 정책 블록
<a name="tag-policy-examples-workgroups-basic"></a>

작업 그룹과 같은 리소스에 연결된 태그를 리소스 태그라고 합니다. 리소스 태그를 사용하면 키-값 페어(예: `stack`, `production`)로 태그가 지정된 작업 그룹에 대해 명시된 작업을 거부하는 다음과 같은 정책 블록을 작성할 수 있습니다.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Deny",
            "Action": [
                "athena:GetWorkGroup",
                "athena:UpdateWorkGroup",
                "athena:DeleteWorkGroup",
                "athena:TagResource",
                "athena:UntagResource",
                "athena:ListTagsForResource",
                "athena:StartQueryExecution",
                "athena:GetQueryExecution",
                "athena:BatchGetQueryExecution",
                "athena:ListQueryExecutions",
                "athena:StopQueryExecution",
                "athena:GetQueryResults",
                "athena:GetQueryResultsStream",
                "athena:CreateNamedQuery",
                "athena:GetNamedQuery",
                "athena:BatchGetNamedQuery",
                "athena:ListNamedQueries",
                "athena:DeleteNamedQuery",
                "athena:CreatePreparedStatement",
                "athena:GetPreparedStatement",
                "athena:ListPreparedStatements",
                "athena:UpdatePreparedStatement",
                "athena:DeletePreparedStatement"
            ],
            "Resource": "arn:aws:athena:us-east-1:123456789012:workgroup/*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/stack": "production"
                }
            }
        }
    ]
}
```

------

### 예 - 지정된 태그에 대한 태그 변경 작업 요청을 제한하는 정책 블록
<a name="tag-policy-examples-workgroups-restricted-specific"></a>

태그를 변경하는 작업에 파라미터로 전달되는 태그(예: 태그가 있는 `TagResource`, `UntagResource`, 또는 `CreateWorkGroup`)를 요청 태그라고 합니다. 다음 예제 정책 블록에서는 전달된 태그 중 하나에 `costcenter` 키와 `1`, `2` 또는 `3` 값이 있는 경우에만 `CreateWorkGroup` 작업을 허용합니다.

**참고**  
IAM 역할이 `CreateWorkGroup` 작업의 일환으로 태그를 전달할 수 있도록 하려면 `TagResource` 및 `CreateWorkGroup` 작업에 대한 권한을 해당 역할에 부여해야 합니다.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "athena:CreateWorkGroup",
                "athena:TagResource"
            ],
            "Resource": "arn:aws:athena:us-east-1:123456789012:workgroup/*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/costcenter": [
                        "1",
                        "2",
                        "3"
                    ]
                }
            }
        }
    ]
}
```

------

## 데이터 카탈로그에 대한 태그 정책 예제
<a name="tag-policy-examples-data-catalogs"></a>

### 예 - 기본 태깅 정책
<a name="tag-policy-examples-data-catalogs-basic"></a>

다음 IAM 정책을 사용하면 `datacatalogA`라는 데이터 카탈로그에 대한 태그와 상호 작용할 수 있습니다.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "athena:ListWorkGroups",
                "athena:ListEngineVersions",
                "athena:ListDataCatalogs",
                "athena:ListDatabases",
                "athena:GetDatabase",
                "athena:ListTableMetadata",
                "athena:GetTableMetadata"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "athena:GetWorkGroup",
                "athena:TagResource",
                "athena:UntagResource",
                "athena:ListTagsForResource",
                "athena:StartQueryExecution",
                "athena:GetQueryExecution",
                "athena:BatchGetQueryExecution",
                "athena:ListQueryExecutions",
                "athena:StopQueryExecution",
                "athena:GetQueryResults",
                "athena:GetQueryResultsStream",
                "athena:CreateNamedQuery",
                "athena:GetNamedQuery",
                "athena:BatchGetNamedQuery",
                "athena:ListNamedQueries",
                "athena:DeleteNamedQuery"
            ],
            "Resource": [
                "arn:aws:athena:us-east-1:123456789012:workgroup/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "athena:CreateDataCatalog",
                "athena:GetDataCatalog",
                "athena:UpdateDataCatalog",
                "athena:DeleteDataCatalog",
                "athena:ListDatabases",
                "athena:GetDatabase",
                "athena:ListTableMetadata",
                "athena:GetTableMetadata",
                "athena:TagResource",
                "athena:UntagResource",
                "athena:ListTagsForResource"
            ],
            "Resource": "arn:aws:athena:us-east-1:123456789012:datacatalog/datacatalogA"
        }
    ]
}
```

------

### 예 - 태그 키와 태그 값 페어를 기반으로 데이터 카탈로그에서 작업을 거부하는 정책 블록
<a name="tag-policy-examples-data-catalogs-deny-actions"></a>

리소스 태그를 사용하여 특정 태그 키-값 페이로 태그가 지정된 데이터 카탈로그에서 특정 작업을 거부하는 정책 블록을 작성할 수 있습니다. 다음 예제 정책은 태그 키-값 페어(`stack`, `production`)가 있는 데이터 카탈로그에 대한 작업을 거부합니다.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Deny",
            "Action": [
                "athena:CreateDataCatalog",
                "athena:GetDataCatalog",
                "athena:UpdateDataCatalog",
                "athena:DeleteDataCatalog",
                "athena:GetDatabase",
                "athena:ListDatabases",
                "athena:GetTableMetadata",
                "athena:ListTableMetadata",
                "athena:StartQueryExecution",
                "athena:TagResource",
                "athena:UntagResource",
                "athena:ListTagsForResource"
            ],
            "Resource": "arn:aws:athena:us-east-1:123456789012:datacatalog/*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/stack": "production"
                }
            }
        }
    ]
}
```

------

### 예 - 지정된 태그에 대한 태그 변경 작업 요청을 제한하는 정책 블록
<a name="tag-policy-examples-data-catalogs-action-specific-tags"></a>

태그를 변경하는 작업에 파라미터로 전달되는 태그(예: 태그가 있는 `TagResource`, `UntagResource`, 또는 `CreateDataCatalog`)를 요청 태그라고 합니다. 다음 예제 정책 블록에서는 전달된 태그 중 하나에 `costcenter` 키와 `1`, `2` 또는 `3` 값이 있는 경우에만 `CreateDataCatalog` 작업을 허용합니다.

**참고**  
IAM 역할이 `CreateDataCatalog` 작업의 일환으로 태그를 전달할 수 있도록 하려면 `TagResource` 및 `CreateDataCatalog` 작업에 대한 권한을 해당 역할에 부여해야 합니다.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "athena:CreateDataCatalog",
                "athena:TagResource"
            ],
            "Resource": "arn:aws:athena:us-east-1:123456789012:datacatalog/*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/costcenter": [
                        "1",
                        "2",
                        "3"
                    ]
                }
            }
        }
    ]
}
```

------

# Service Quotas
<a name="service-limits"></a>

**참고**  
Service Quotas 콘솔은 Amazon Athena 할당량에 대한 정보를 제공합니다. Service Quotas 콘솔을 사용하여 조정 가능한 할당량에 대한 [할당량 증가를 요청](https://console.aws.amazon.com/servicequotas/home?region=us-east-1#!/services/athena/quotas)할 수도 있습니다. AWS Glue 관련 스키마 제한은 [AWS Glue 엔드포인트 및 할당량](https://docs.aws.amazon.com/general/latest/gr/glue.html) 페이지를 참조하세요. AWS 서비스 할당량에 대한 일반적인 정보는 *AWS 일반 참조*의 [AWS 서비스 할당량](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html)을 참조하세요.

## 쿼리
<a name="service-limits-queries"></a>

계정에는 Amazon Athena에 대해 다음과 같은 쿼리 관련 할당량이 있습니다. 자세한 내용은 AWS 일반 참조의 [Amazon Athena 엔드포인트 및 할당량](https://docs.aws.amazon.com/general/latest/gr/athena.html#amazon-athena-limits)을 참조하세요.
+ **활성 DDL 쿼리(Active DDL queries)** - 활성 DDL 쿼리 수입니다. DDL 쿼리에는 `CREATE TABLE` 및 `ALTER TABLE ADD PARTITION` 쿼리가 포함됩니다.
+ **DDL 쿼리 제한 시간(DDL query timeout)** - DDL 쿼리가 취소되기 전에 실행할 수 있는 최대 시간(분)입니다.
+ **활성 DML 쿼리(Active DML queries)** - 활성 DML 쿼리 수입니다. DML 쿼리에는 `SELECT`, `CREATE TABLE AS`(CTAS) 및 `INSERT INTO` 쿼리가 포함됩니다. 구체적인 할당량은 AWS 리전에 따라 다릅니다.
+ **DDL 쿼리 제한 시간(DML query timeout)** - DML 쿼리가 취소되기 전에 실행할 수 있는 최대 시간(분)입니다. 이 제한 시간을 최대 240분까지 늘리도록 요청할 수 있습니다.

할당량 증가를 요청하려면 [Athena Service Quotas](https://console.aws.amazon.com/servicequotas/home?region=us-east-1#!/services/athena/quotas) 콘솔을 사용합니다.

Athena는 전체 서비스 부하와 수신 요청 수에 따라 리소스를 할당하여 쿼리를 처리합니다. 쿼리는 실행되기 전에 일시적으로 대기열에 머무를 수 있습니다. 비동기 프로세스는 대기열에서 쿼리를 선택하고 리소스가 가용 상태가 되는 즉시 물리적 리소스에서 쿼리를 실행합니다. 단, 계정 구성이 이를 허용해야 합니다.

활성 DML 쿼리 및 활성 DDL 쿼리 할당량에는 실행 중인 쿼리와 대기열에 있는 쿼리가 모두 포함됩니다. 예를 들어 활성 DML 쿼리 할당량이 25이고 실행 중인 쿼리와 대기 중인 쿼리의 합계가 26인 경우 쿼리 26은 TooManyRequestsException 오류를 발생시킵니다.

**참고**  
Athena에서 실행하는 쿼리의 동시성을 직접 제어하려는 경우 용량 예약을 사용할 수 있습니다. 자세한 내용은 [쿼리 처리 용량 관리](capacity-management.md) 섹션을 참조하세요.

### 쿼리 문자열 길이
<a name="service-limits-query-string-length"></a>

허용되는 최대 쿼리 문자열 길이는 262144바이트이며, 문자열은 UTF-8로 인코딩됩니다. 이 할당량은 조정 가능한 할당량이 아닙니다. 그러나 긴 쿼리를 여러 개의 작은 쿼리로 분할하여 이러한 제한을 해결할 수 있습니다. 자세한 내용은 AWS 지식 센터에서 [Athena의 최대 쿼리 문자열 길이를 늘리려면 어떻게 해야 합니까?](https://aws.amazon.com/premiumsupport/knowledge-center/athena-query-string-length/)를 참조하세요.

## 작업 그룹
<a name="service-limits-workgroups"></a>

Athena 작업 그룹으로 작업할 때는 다음 사항을 기억하세요.
+ Athena 서비스 할당량은 계정의 모든 작업 그룹 간에 공유됩니다.
+ 한 계정에서 리전별로 생성할 수 있는 최대 작업 그룹 수는 1,000개입니다.
+ 작업 그룹에서 준비된 문의 최대 개수는 1000입니다.
+ 작업 그룹당 최대 태그 수는 50개입니다. 자세한 내용은 [태그 제한 사항](tags.md#tag-restrictions) 단원을 참조하세요.

## 데이터베이스, 테이블, 파티션
<a name="service-limits-glue"></a>

Athena는 AWS Glue Data Catalog을(를) 사용합니다. 테이블, 데이터베이스, 파티션에 대한 서비스 할당량(예: 계정당 최대 데이터베이스 또는 테이블 수)은 [AWS Glue 엔드포인트 및 할당량](https://docs.aws.amazon.com/general/latest/gr/glue.html)을 참조하세요. Athena는 1천만 개의 파티션이 있는 AWS Glue 테이블에 대한 쿼리를 지원하지만, 단일 스캔으로 1백만 개 이상의 파티션을 읽을 수 없습니다.

## Amazon S3 버킷
<a name="service-limits-buckets"></a>

Amazon S3 버킷으로 작업할 때는 다음 사항을 기억하세요.
+ Amazon S3에는 계정당 버킷 10,000개의 기본 서비스 할당량이 있습니다.
+ Athena에는 결과를 기록하기 위해 별도의 버킷이 필요합니다.
+ AWS 계정당 Amazon S3 버킷 최대 1백만 개의 할당량 증가를 요청할 수 있습니다.

## 계정당 API 호출 할당량
<a name="service-limits-api-calls"></a>

Athena API에는 계정당(쿼리당이 아님) API 직접 호출 수에 기본 할당량이 있습니다. 기본 할당량의 전체 목록은 AWS 일반 참조 가이드의 [Service Quotas](https://docs.aws.amazon.com/general/latest/gr/athena.html#amazon-athena-limits) 표를 참조하세요.

이러한 API를 사용하고 초당 호출 수의 기본 할당량 또는 계정의 버스트 용량을 초과하는 경우, Athena API는 ""ClientError: An error occurred (ThrottlingException) when calling the *<API\$1name>* operation: Rate exceeded"와 유사한 오류를 생성합니다. 초당 호출 수 또는 이 계정의 API에 대한 버스트 용량을 줄입니다.

계정별 API 직접 호출에 대한 Athena 할당량은 [Athena Service Quotas 콘솔](https://console.aws.amazon.com/servicequotas/home?region=us-east-1#!/services/athena/quotas)에서 변경할 수 있습니다.