파티션 인덱스 생성 - AWS Glue

파티션 인덱스 생성

시간이 지남에 따라 수십만 개의 파티션이 테이블에 추가됩니다. GetPartitions API는 테이블의 파티션을 가져오는 데 사용됩니다. API는 요청에 제공된 표현식과 일치하는 파티션을 반환합니다.

Country, Category, Year, Month, creationDate 키로 분할된 sales_data 테이블을 예로 들어 보겠습니다. 2020년 2020-08-15 이후에 도서 카테고리에서 판매된 모든 상품에 대한 판매 데이터를 얻으려면 데이터 카탈로그에 "Category = 'Books' 및 creationDate > '2020-08-15'"라는 표현으로 GetPartitions 요청을 해야 합니다.

테이블에 파티션 인덱스가 없으면 AWS Glue는 테이블의 모든 파티션을 로드한 다음 GetPartitions 요청에서 사용자가 제공한 쿼리 표현식을 사용하여 로드된 파티션을 필터링합니다. 인덱스가 없는 테이블에서 파티션 수가 증가하면 쿼리를 실행하는 데 더 많은 시간이 걸립니다. 인덱스를 사용하면 GetPartitions 쿼리는 테이블의 모든 파티션을 로드하는 대신 파티션의 하위 집합을 가져오려고 시도합니다.

파티션 인덱스 정보

파티션 인덱스를 생성할 때 지정된 테이블에 이미 존재하는 파티션 키 목록을 지정합니다. 파티션 인덱스는 테이블에 정의된 파티션 키의 하위 목록입니다. 테이블에 정의된 파티션 키의 순열에 대해 파티션 인덱스를 생성할 수 있습니다. 위의 sales_data 테이블에 대해 가능한 인덱스는 (country, category, creationDate), (country, category, year), (country, category), (country), (category, country, year, month) 등입니다.

Data Catalog는 인덱스 생성 시 제공된 순서대로 파티션 값을 연결합니다. 인덱스는 파티션이 테이블에 추가될 때 일관되게 구축됩니다. 문자열(string, char, varchar), 숫자(int, bigint, long, tinyint, smallint), 날짜(yyyy-MM-dd) 열 유형에 대한 인덱스를 생성할 수 있습니다.

지원되는 데이터 유형

  • 날짜 - ISO 형식의 날짜(예: YYYY-MM-DD)입니다. 예를 들어 날짜 2020-08-15입니다. 형식은 하이픈(-)을 사용하여 연도, 월, 일을 구분합니다. 인덱싱에 허용되는 날짜 범위는 0000-01-01에서 9999-12-31까지입니다.

  • String - 작은따옴표 또는 큰따옴표로 묶인 문자열 리터럴입니다.

  • Char - 길이가 1~255자로 지정된 고정 길이 문자 데이터입니다(예: char(10)).

  • Varchar - 길이가 1~65535자로 지정된 가변 길이 문자 데이터입니다(예: varchar(10)).

  • 숫자 - int, bigint, long, tinyint, smallint

숫자, 문자열, 날짜 데이터 유형에 대한 인덱스는 =, >, >=, <, <=, between 연산자를 지원합니다. 인덱싱 솔루션은 현재 AND 논리 연산자만 지원합니다. "LIKE", "IN", "OR" 및 "NOT" 연산자가 있는 하위 표현식은 인덱스를 사용하여 필터링하는 표현식에서 무시됩니다. 무시된 하위 표현식에 대한 필터링은 인덱스 필터링을 적용한 후 가져온 파티션에서 수행됩니다.

테이블에 추가된 각 파티션에 대해 해당 인덱스 항목이 생성됩니다. 'n'개의 파티션이 있는 테이블의 경우 1개의 파티션 인덱스는 'n'개의 파티션 인덱스 항목을 생성합니다. 동일한 테이블의 'm' 파티션 인덱스는 'm*n' 파티션 인덱스 항목이 됩니다. 각 파티션 인덱스 항목은 데이터 카탈로그 스토리지에 대한 현재 AWS Glue 가격 정책에 따라 요금이 부과됩니다. 스토리지 객체 요금에 대한 자세한 내용은 AWS Glue 요금을 참조하세요.

파티션 인덱스로 테이블 생성

테이블 생성 중 파티션 인덱스를 생성할 수 있습니다. CreateTable 요청은 PartitionIndex 객체 목록을 입력으로 사용합니다. 지정된 테이블에 최대 3개의 파티션 인덱스를 생성할 수 있습니다. 각 파티션 인덱스에는 테이블에 대해 정의된 이름과 partitionKeys 목록이 필요합니다. 테이블에 생성된 인덱스는 GetPartitionIndexes API를 사용하여 가져올 수 있습니다.

기존 테이블에 파티션 인덱스 추가

파티션 인덱스를 기존 테이블에 추가하려면 CreatePartitionIndex 작업을 사용합니다. 단, CreatePartitionIndex 작업당 PartitionIndex 하나를 생성할 수 있습니다. 인덱스가 생성되는 동안 테이블을 계속 사용할 수 있으므로 인덱스를 추가해도 테이블의 가용성에는 영향이 없습니다.

추가된 파티션의 인덱스 상태는 CREATING으로 설정되고 인덱스 데이터 생성이 시작됩니다. 인덱스 생성 프로세스가 성공하면 indexStatus가 ACTIVE로 업데이트되고 실패한 프로세스에 대해 인덱스 상태가 FAILED로 업데이트됩니다. 인덱스 생성은 여러 가지 이유로 실패할 수 있으며 GetPartitionIndexes 작업을 사용하여 실패 세부 정보를 검색할 수 있습니다. 가능한 실패는 다음과 같습니다.

  • ENCRYPTED_PARTITION_ERROR - 암호화된 파티션이 있는 테이블에 대한 인덱스 생성은 지원되지 않습니다.

  • INVALID PARTITION TYPE DATA_ERROR - partitionKey 값이 해당 partitionKey 데이터 유형에 대해 유효한 값이 아닐 때 관찰됩니다. 예: 'int' 데이터 유형을 가진 partitionKey는 'foo' 값을 갖습니다.

  • MISSING PARTITION VALUE_ERROR - indexedKey에 대한 partitionValue가 없을 때 관찰됩니다. 이는 테이블이 일관되게 분할되지 않은 경우에 발생할 수 있습니다.

  • UNSUPPORTED_PARTITION_CHARACTER_ERROR - 인덱싱된 파티션 키의 값에 \u0000, \u0001 또는 \u0002 문자가 포함될 때 관찰됩니다.

  • INTERNAL_ERROR - 인덱스를 생성하는 동안 내부 오류가 발생했습니다.

테이블의 파티션 인덱스 설명

테이블에 생성된 파티션 인덱스를 가져오려면 GetPartitionIndexes 연산을 사용합니다. 응답은 현재 각 인덱스 상태(IndexStatus)와 함께 테이블의 모든 인덱스를 반환합니다.

파티션 인덱스의 IndexStatus는 다음 중 하나가 됩니다.

  • CREATING - 현재 인덱스를 생성 중이며, 아직 사용할 수 없습니다.

  • ACTIVE - 인덱스를 사용할 준비가 되었습니다. 요청은 인덱스를 사용하여 최적화된 쿼리를 수행할 수 있습니다.

  • DELETING - 현재 인덱스를 삭제하고 있으며 더 이상 사용할 수 없습니다. 활성 상태의 인덱스는 상태를 ACTIVE에서 DELETING으로 이동하는 DeletePartitionIndex 요청을 사용하여 삭제할 수 있습니다.

  • FAILED - 기존 테이블에 대한 인덱스 생성에 실패했습니다. 각 테이블은 마지막 10개의 실패한 인덱스를 저장합니다.

기존 테이블에 생성된 인덱스의 가능한 상태 전환은 다음과 같습니다.

  • CREATING → ACTIVE → DELETING

  • CREATING → FAILED

파티션 인덱스 사용에 대한 제한 사항

파티션 인덱스를 생성한 후에는 테이블 및 파티션 기능에 대한 다음 변경 사항을 확인합니다.

새 파티션 생성(인덱스 추가 후)

테이블에 파티션 인덱스가 생성된 후 테이블에 추가된 모든 새 파티션은 인덱싱된 키에 대한 데이터 유형 검사에 대해 검증됩니다. 인덱싱된 키의 파티션 값은 데이터 유형 포맷에 대해 검증됩니다. 데이터 유형 검사가 실패하면 파티션 생성 작업이 실패합니다. sales_data 테이블의 경우 범주가 string 유형이고 연도가 int 유형인 키(category, year)에 대한 인덱스가 생성되면 YEAR 값이 "foo"인 새 파티션 생성이 실패합니다.

인덱스가 사용되면 U+0000, U+00001 및 U+0002 문자가 있는 인덱스 키 값이 있는 파티션 추가가 실패하기 시작합니다.

테이블 업데이트

테이블에 파티션 인덱스가 생성되면 기존 파티션 키의 파티션 키 이름을 수정할 수 없으며 인덱스에 등록된 키의 유형이나 순서를 변경할 수 없습니다.

최적화된 GetPartitions 호출에 인덱스 사용

인덱스가 있는 테이블에서 GetPartitions를 호출할 때 표현식을 포함할 수 있으며 해당하는 경우 Data Catalog는 가능한 경우 인덱스를 사용합니다. 인덱스의 첫 번째 키는 필터링에 사용할 인덱스에 대한 표현식에 전달되어야 합니다. 필터링의 인덱스 최적화는 최선의 노력으로 적용됩니다. Data Catalog는 가능한 한 인덱스 최적화를 사용하려고 시도하지만 인덱스가 누락되거나 지원되지 않는 연산자의 경우 모든 파티션을 로드하는 기존 구현으로 폴백합니다.

위의 sales_data 테이블에 대해 인덱스 [Country, Category, Year]를 추가합니다. 표현식에 "Country"가 전달되지 않으면 등록된 인덱스가 인덱스를 사용하여 파티션을 필터링할 수 없습니다. 다양한 쿼리 패턴을 지원하기 위해 최대 3개의 인덱스를 추가할 수 있습니다.

몇 가지 예제 표현식을 사용하여 인덱스가 어떻게 작동하는지 살펴보겠습니다.

Expressions 인덱스 사용 방법

Country = 'US'

파티션을 필터링하는 데 인덱스가 사용됩니다.

Country = 'US' 및 Category = 'Shoes'

파티션을 필터링하는 데 인덱스가 사용됩니다.

Category = 'Shoes'

표현식에 "country"가 제공되지 않으므로 인덱스는 사용되지 않습니다. 응답을 반환하기 위해 모든 파티션이 로드됩니다.

Country = 'US', Category = 'Shoes' 및 Year > '2018'

파티션을 필터링하는 데 인덱스가 사용됩니다.

Country = 'US', Category = 'Shoes', Year > '2018' 및 month = 2

country = "US", category = "shoes", year > 2018인 모든 파티션을 가져오는 데 인덱스가 사용됩니다. 그런 다음 월 표현식에 대한 필터링이 수행됩니다.

Country = 'US' AND Category = 'Shoes' OR Year > '2018'

표현식에 OR 연산자가 있으므로 인덱스가 사용되지 않습니다.

Country = 'US' AND Category = 'Shoes' AND (Year = 2017 OR Year = '2018')

country = "US" 및 category = "shoes"인 모든 파티션을 가져오는 데 인덱스가 사용된 다음 연도 표현식에 대한 필터링이 수행됩니다.

Country in ('US', 'UK') AND Category = 'Shoes'

IN 연산자는 현재 지원되지 않으므로 필터링에 인덱스가 사용되지 않습니다.

Country = 'US' AND Category in ('Shoes', 'Books')

country = "US"인 모든 파티션을 가져오는 데 인덱스가 사용된 다음 범주 표현식에 대한 필터링이 수행됩니다.

Country = 'US' AND Category in ('Shoes', 'Books') AND (creationDate > '2023-9-01'

country = "US" 및 creationDate > '2023-9-01'인 모든 파티션을 가져오는 데 인덱스가 사용된 다음 범주 표현식에 대한 필터링이 수행됩니다.

엔진과의 통합

Redshift Spectrum, Amazon EMR 및 AWS Glue ETL Spark DataFrames는 인덱스가 AWS Glue에서 ACTIVE 상태인 후 파티션을 가져 오기 위해 인덱스를 사용할 수 있습니다. AthenaAWS Glue ETL 동적 프레임에서 쿼리 개선을 위해 인덱스를 활용하려면 추가 단계를 따라야 합니다.

파티션 필터링 사용 설정

Athena에서 파티션 필터링을 사용하려면 다음과 같이 테이블 속성을 업데이트해야 합니다.

  1. AWS Glue 콘솔의 데이터 카탈로그에서 테이블을 선택합니다.

  2. 테이블을 선택합니다.

  3. 작업에서 테이블 편집을 선택합니다.

  4. 테이블 속성에서 다음을 추가합니다.

    • 키 - partition_filtering.enabled

    • 값 - true

  5. 적용을 선택합니다.

또는 Athena에서 ALTER TABLE SET PROPERTIES 쿼리를 실행하여 이 파라미터를 설정할 수도 있습니다.

ALTER TABLE partition_index.table_with_index SET TBLPROPERTIES ('partition_filtering.enabled' = 'true')