Athena에서 파티셔닝 및 버킷팅 - Amazon Athena

Athena에서 파티셔닝 및 버킷팅

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

파티셔닝이란 무엇인가요?

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

파티셔닝 방법 결정

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

파티셔닝된 테이블 생성

데이터 세트가 파티셔닝되면 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 유형이어야 합니다. 자세한 내용은 파티션 키의 데이터 형식으로 문자열 사용 섹션을 참조하세요.

추가적인 CREATE TABLECREATE TABLE AS 구문 세부 정보는 CREATE TABLECTAS 테이블 속성 섹션을 참조하세요.

파티셔닝된 테이블 쿼리

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

sales_dateproduct_category를 기준으로 파티셔닝된 테이블이 있고 특정 카테고리에서 1주일 간의 총 수익을 알고자 합니다. Athena가 다음 예제와 같이 최소의 데이터만 스캔하도록 하기 위해 sales_dateproduct_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 테이블 쿼리 사이의 이러한 차이에 대한 자세한 내용은 시간을 기준으로 파티셔닝된 타임스탬프 필드에 대한 쿼리를 작성하는 방법 섹션을 참조하세요.

버킷팅이란 무엇인가요?

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

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

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

버킷팅의 장점

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

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

참고

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

버킷팅된 열에 대한 필터링에 지원되는 데이터 형식

특정 데이터 형식으로 버킷팅된 열에 필터를 추가할 수 있습니다. Athena는 다음과 같은 데이터 형식의 버킷팅된 열에서 필터링을 지원합니다.

  • BOOLEAN

  • BYTE

  • 날짜

  • DOUBLE

  • FLOAT

  • INT

  • LONG

  • SHORT

  • STRING

  • VARCHAR

Hive 및 Spark 지원

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

참고

Athena는 CREATE TABLE AS SELECT(CTAS) 쿼리당 파티션을 100개로 제한합니다. 마찬가지로, INSERT INTO 문을 통해 대상 테이블에 최대 100개의 파티션만 추가할 수 있습니다. 이 100개의 한도는 테이블이 버킷팅 및 파티셔닝된 경우에만 적용됩니다.

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

CREATE TABLE 버킷팅 예제

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

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

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

CREATE TABLE AS(CTAS) 버킷팅 예제

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

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

버킷팅 쿼리 예제

다음 쿼리 예제는 특정 고객이 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는 파티션당 최대 하나의 파일 정도만 읽습니다.

추가 리소스