벤치마크·프로파일링 실습
DuckDB 쿼리를 파일 레이아웃과 세션 설정별로 비교하고 재현 가능한 벤치마크·프로파일링 절차를 만드는 실습 가이드입니다.
핵심 요약
- DuckDB version과 input manifest를 고정한 뒤 cold/warm cache를 나눠 측정하고,
EXPLAIN ANALYZE로 scan·filter·aggregate·sort 시간 분포를 봅니다. - 한 번에 하나의 변수만 바꿉니다. 파일 레이아웃을 바꾸면 쿼리·세션 설정을 그대로 두고, 세션 설정을 바꾸면 입력 파일을 그대로 둡니다.
- 비교 축은 CSV vs Parquet, 정렬 전/후 Parquet(zonemap), row group size,
threads,memory_limit입니다. - 숫자 하나만 보지 말고 plan shape이 바뀌었는지 확인하고, version·client·settings·cold/warm runtime·결론을 기록 양식에 남깁니다.
- thread를 늘려도 안 빨라지면 single file/row group이나 I/O bottleneck을, warm cache만 빠르면 storage latency가 지배한다고 해석합니다.
성능 튜닝 문서는 숫자보다 절차가 중요합니다. 노트북에서 한 번 빠르게 나온 결과는 OS cache, thread 수, 파일 layout, object storage latency에 쉽게 흔들립니다. 이 장에서 "우리 환경에서 같은 쿼리를 어떻게 비교할지"를 표준 절차로 정리합니다.
실습 목표
| 비교 | 질문 |
|---|---|
| CSV vs Parquet | 반복 분석 전에 columnar 변환이 필요한가 |
| 정렬 전/후 Parquet | zonemap 효과가 있는가 |
| row group size | 병렬성과 metadata overhead 균형이 맞는가 |
threads | CPU thread 증가가 실제 runtime을 줄이는가 |
memory_limit | spill 없이 안정적으로 실행되는 하한은 어디인가 |
절차
기준 SQL
SET threads = 4;
SET memory_limit = '8GB';
SET preserve_insertion_order = false;
EXPLAIN ANALYZE
SELECT
region,
plan,
sum(amount) AS revenue,
count(*) AS orders
FROM read_parquet('/tmp/duckdb-advanced-orders.parquet')
WHERE ordered_at >= TIMESTAMP '2026-05-01 00:00:00'
GROUP BY ALL
ORDER BY ALL;EXPLAIN ANALYZE 결과에서 scan, filter, aggregate, sort의 시간이 어디에 몰리는지 먼저 봅니다. 숫자 하나만 보지 말고 plan shape이 바뀌었는지 확인합니다.
한 번에 하나만 바꾼다
SET threads = 1;
-- same query
SET threads = 4;
-- same queryCOPY (
SELECT *
FROM orders
ORDER BY ordered_at, customer_id
) TO '/tmp/duckdb-advanced-orders-rg.parquet'
(FORMAT parquet, COMPRESSION zstd, ROW_GROUP_SIZE 100000);파일 레이아웃을 바꿨다면 쿼리와 세션 설정을 그대로 둡니다. 세션 설정을 바꿨다면 입력 파일을 그대로 둡니다.
기록 양식
| 항목 | 값 |
|---|---|
| DuckDB version | SELECT version() |
| client | CLI / Python / dbt-duckdb / Ibis |
| input manifest | 파일 수, 전체 크기, row group 수 |
| settings | threads, memory_limit, temp_directory |
| cold run | runtime, 주요 병목 |
| warm run | runtime, 주요 병목 |
| 결론 | 채택할 파일 layout 또는 세션 설정 |
해석 기준
| 관찰 | 해석 |
|---|---|
| thread를 늘려도 빨라지지 않음 | single file/row group, I/O bottleneck, blocking operator 가능 |
| 정렬 후 selective filter가 빨라짐 | zonemap 효과 가능 |
| Parquet가 CSV보다 훨씬 빠름 | 반복 분석 전 변환 가치 있음 |
| memory를 늘려도 변화 없음 | CPU/I/O 또는 file layout 병목 |
| warm cache만 빠름 | storage latency가 지배적일 수 있음 |