최종 수정: 에
파티션 프루닝 최적화: Doris 쿼리 성능 튜닝
Partition Pruning은 쿼리 조건을 바탕으로 관련 파티션을 지능적으로 식별하여 해당 파티션만 스캔하고 관련 없는 파티션은 건너뛰는 쿼리 최적화 기법입니다.
Doris는 파티션 프루닝을 통해 I/O와 연산량을 크게 줄여 대용량 테이블의 쿼리 속도를 높일 수 있습니다.
적용 여부 확인 목록:
- 테이블이 업무에 사용하는 컬럼(예: 날짜)을 기준으로 파티셔닝되어 있습니다.
- 쿼리 조건에 파티션 컬럼에 대한 필터(예:
WHERE date BETWEEN ...)가 포함되어 있습니다. - 스캔하는 파티션 수를 줄이고 I/O를 낮추고자 합니다.
EXPLAIN으로 프루닝 적용 여부를 확인해야 합니다.
사례: 날짜별로 파티셔닝된 매출 테이블
다음 사례는 Doris의 파티션 프루닝 기능을 보여 줍니다.
1. 테이블 생성: 날짜 기준 범위 파티셔닝
목표: 매출 데이터 테이블 sales를 날짜 기준으로 파티셔닝하여 월별로 파티션을 하나씩 생성합니다.
명령:
CREATE TABLE sales (
date DATE,
product VARCHAR(50),
amount DECIMAL(10, 2)
)
PARTITION BY RANGE(date) (
PARTITION p1 VALUES LESS THAN ('2023-01-01'),
PARTITION p2 VALUES LESS THAN ('2023-02-01'),
PARTITION p3 VALUES LESS THAN ('2023-03-01'),
PARTITION p4 VALUES LESS THAN ('2023-04-01')
)
DISTRIBUTED BY HASH(date) BUCKETS 16
PROPERTIES
(
"replication_num" = "1"
);
설명: 파티션 컬럼은 date입니다. 파티션은 총 4개이며, 각 파티션은 한 달 분량의 데이터를 포함합니다.
2. 쿼리: 파티션 컬럼에 필터 적용
목표: 2023년 일월 15일부터 2023년 이월 15일까지의 총매출액을 조회합니다.
명령:
SELECT SUM(amount) AS total_amount
FROM sales
WHERE date BETWEEN '2023-01-15' AND '2023-02-15';
설명: WHERE 절에 파티션 컬럼 date에 대한 범위 필터가 포함되어 있습니다. 이는 파티션 프루닝을 활성화하는 핵심 조건입니다.
3. 파티션 프루닝 실행 과정
| 단계 | Doris 동작 | 결과 |
|---|---|---|
| 1 | 쿼리 조건의 파티션 컬럼 date 분석 | 2023-01-15부터 2023-02-15까지의 날짜 범위 식별 |
| 2 | 쿼리 조건과 파티션 정의 비교 | 조건에 맞는 파티션 p2와 p3 선택 |
| 3 | 관련 없는 파티션 자동으로 건너뛰기 | p1과 p4 건너뛰기 |
| 4 | 조건에 맞는 파티션에서만 스캔 및 집계 수행 | 결과를 빠르게 반환 |
4. EXPLAIN으로 프루닝 검증
목표: EXPLAIN 명령으로 실행 계획을 살펴보고 실제로 스캔하는 파티션 수를 확인합니다.
명령:
EXPLAIN SELECT SUM(amount) AS total_amount
FROM sales
WHERE date BETWEEN '2023-01-15' AND '2023-02-15';
주요 출력:
| 0:VOlapScanNode(212) |
| TABLE: cir.sales(sales), PREAGGREGATION: ON |
| PREDICATES: (date[#0] >= '2023-01-15') AND (date[#0] <= '2023-02-15') |
| partitions=2/4 (p2,p3) |
설명: partitions=2/4 (p2,p3) 필드가 OlapScanNode에 표시되면 전체 4개 파티션 중 2개(p2와 p3)만 스캔된다는 뜻이며, 파티션 프루닝이 적용되었음을 의미합니다.
비교: 프루닝이 적용되는 경우와 적용되지 않는 경우
| 구분 | 파티션 프루닝이 적용되는 경우 | 파티션 프루닝이 적용되지 않는 경우 |
|---|---|---|
| 쿼리 조건 | 파티션 컬럼에 대한 필터 포함 | 파티션 컬럼 조건이 없거나 파티션 컬럼에 함수 적용 |
| 스캔하는 파티션 수 | 조건에 맞는 파티션만 스캔 | 모든 파티션 스캔 |
| I/O 오버헤드 | 낮음 | 높음 |
| EXPLAIN 출력 | partitions=N/M (N < M) | partitions=M/M |
자주 묻는 질문
Q1: 쿼리가 느려서 파티션 프루닝이 적용되지 않는 것으로 의심됩니다. 어떻게 확인하나요?
EXPLAIN <query>를 실행하고 partitions=N/M 필드를 OlapScanNode에서 확인하세요. N == M이면 모든 파티션을 스캔하므로 프루닝이 적용되지 않은 것입니다.
Q2: WHERE에 파티션 컬럼이 포함되어 있는데도 쿼리가 모든 파티션을 스캔하는 이유는 무엇인가요?
일반적인 원인은 다음과 같습니다.
- 파티션 컬럼에 함수(예:
DATE_FORMAT(date, ...))가 적용되어 있어 옵티마이저가 범위를 도출할 수 없습니다. - 타입이 일치하지 않습니다. 예를 들어 파티션 컬럼은
DATE타입인데 필터 값은 암시적으로 변환할 수 없는 문자열인 경우입니다. OR로 파티션 컬럼이 아닌 컬럼의 조건이 연결되어 있어 조건을 푸시다운할 수 없습니다.
Q3: 파티션 프루닝과 버킷 프루닝은 어떻게 다른가요?
- Partition Pruning:
PARTITION BY컬럼을 기준으로 파티션을 프루닝합니다. - Bucket Pruning / Tablet Pruning:
DISTRIBUTED BY HASH컬럼에 대한 동등 조건을 기준으로 태블릿을 프루닝합니다. 두 방법을 함께 사용하면 스캔하는 데이터양을 더욱 줄일 수 있습니다.
요약
- 파티션 프루닝은 쿼리 조건과 파티션 간의 대응 관계를 자동으로 식별하고 필요한 파티션만 스캔합니다.
- 핵심 전제 조건은 테이블이 업무에 사용하는 컬럼을 기준으로 파티셔닝되어 있고, 쿼리에 파티션 컬럼에 대한 푸시다운 가능한 필터 조건이 포함되어 있어야 한다는 것입니다.
partitions=N/M필드를EXPLAIN에서 확인하면 프루닝 적용 여부를 빠르게 검증할 수 있습니다.- 파티션 프루닝을 적절히 활용하면 I/O와 연산 오버헤드를 크게 줄여 대규모 데이터셋의 쿼리 속도를 높일 수 있습니다.