글을 쓰게 된 배경
데이터 레이크를 운영하다 보면 한 가지 벽에 부딪힙니다. Hive 테이블은 한번 적재하면 그 자체로는 문제가 없지만, 데이터가 쌓이고 쿼리가 복잡해지면서 구조적 한계가 드러납니다.
파티션 단위로만 가능한 데이터 접근, — 이런 제약은 운영 초기에는 감내할 수 있지만, 테이블이 수백 개로 늘어나면 비용과 운영 복잡도가 함께 올라갑니다.UPDATE나 DELETE 같은 행 수준 변경의 부재, 스키마 변경 시 전체 재적재를 해야하는 문제까지
최근 데이터 플랫폼 영역에서 Open Table Format(OTF) — Apache Iceberg, Delta Lake, Apache Hudi — 가 주목받는 이유가 여기에 있습니다. 기존 Parquet/ORC 파일 위에 메타데이터 레이어를 얹어, 행 수준 ACID 트랜잭션, 스키마 에볼루션, 타임 트래블, 파티션 프루닝 같은 기능을 데이터 레이크 위에서 가능하게 합니다. 데이터 웨어하우스의 기능을 레이크에 가져오는 것, 이른바 Lakehouse 패러다임의 핵심 기술입니다.
저희는 작년 후반부터 핵심 테이블을 점진적으로 Apache Iceberg 포맷으로 옮기기 시작했고, 지금은 약 350여 개 테이블이 Iceberg, 나머지가 Hive 포맷으로 공존하고 있습니다.
참고: CDC가 데이터 플랫폼을 바꾸는 방식: CDC-based Incremental Replication
이 과정에서 가장 자주 받은 질문이 이겁니다.
“Iceberg가 더 효율적이라는 건 알겠는데, 실제로 얼마나?”
인터넷에는 “Iceberg는 메타데이터 프루닝 덕분에 효율적이다” 라는 이론적 설명은 많지만, 실제 운영 데이터로 측정한 사례는 의외로 드뭅니다. 외부 자료 대부분은 합성 데이터 (TPC-DS, NYC Taxi 등)나 단순 비교 차트에 머물러 있어서, 도입 의사결정에 직접 쓰기 어려웠습니다.
이 글은 저희가 실제 운영 중인 테이블 위에서 직접 측정한 기록입니다.
단순한 SELECT 한 줄부터 매주 돌리는 DPD 추세 쿼리까지,
같은 SQL을 Iceberg와 Hive 양쪽에 동시에 던져 보고 그 차이를 측정했습니다.
또한 “이론과 실제가 어디서 어긋나는지” — Iceberg가 오히려 느려지는 영역, 부분 마이그레이션이 함정에 빠지는 패턴, Spark과 Athena의 옵티마이저가 서로 다르게 반응하는 케이스 — 까지 함께 정리했습니다.
이 글의 독자
Iceberg 도입을 검토 중인 데이터 엔지니어 — 비용·운영 측면의 실제 이득과 함정
Iceberg 테이블을 마주한 분석가 — 같은 테이블에서 SQL을 어떻게 써야 빠른가
각 섹션에서 두 독자에게 의미 있는 포인트를 함께 짚어보겠습니다.
1. Warm-up — 가장 단순한 SELECT
먼저 가장 단순한 쿼리부터 시작합니다. 같은 원천(MySQL)에서 CDC로 흘러온 동일한 데이터가 Iceberg 테이블과 Hive 테이블 양쪽에 적재되어 있고, 그 위에 1주일치를 조회합니다.
-- Iceberg 버전
SELECT loan_id, installment, duedate, obligations_met_on_date
FROM iceberg_db.outcome_event
WHERE created_at >= TIMESTAMP '2026-03-01 00:00:00'
AND created_at < TIMESTAMP '2026-03-08 00:00:00'
AND obligations_met_on_date IS NOT NULL;
-- Hive 버전 — FROM 만 hive_db.outcome_event 로 바꾼 동일 쿼리3회 평균 결과:
단순 SELECT 하나에서 스캔량과 비용이 120배 이상 차이가 납니다. 그런데 실행 시간은 Hive가 오히려 살짝 빠릅니다.
이 결과만으로 두 가지 관찰이 나옵니다.
비용은 극적으로 줄지만, 작은 쿼리의 체감 속도는 비슷하거나 오히려 Hive가 빠르다. Iceberg는 manifest를 먼저 읽어 어떤 파일을 열지 결정하는 플래닝 오버헤드가 있고, 작은 쿼리에서는 이 오버헤드가 파일 가지치기의 이득을 상쇄합니다. 위 측정에서도 Iceberg 플래닝 시간은 0.69s, Hive는 0.10s로 일곱 배 차이입니다.
Hive는 1주일치를 조회하려고 5 GB를 스캔했다. 같은 1주일치 데이터를 Iceberg는 40 MB만 읽고 끝냈는데, Hive는 그 127배를 읽고 같은 답을 냈습니다. 이 차이가 어디서 오는지 다음 섹션에서 짚어봅니다.
2. 같은 1주일을 두고, 왜 100배 차이가 났을까
핵심은 “파일을 어떻게 찾는가” 입니다.
Hive — 폴더를 LIST하고 모두 연다
Apache Hive (2008, Facebook). “테이블 = S3 폴더 + 스키마” 라는 가장 오래된 정의.
Hive에서 테이블은 S3 디렉토리 그 자체입니다. 카탈로그(Glue)는 폴더 위치와 스키마, 그리고 등록된 파티션 목록만 알고 있습니다. 개별 파일은 모릅니다.
쿼리가 들어오면 Athena는:
Glue에 폴더 위치를 물어보고
그 폴더를 S3 LIST해서 파일 목록을 만든 뒤
각 파일의 Parquet footer를 열어 통계를 읽고
WHERE 조건과 footer 통계가 맞지 않는 파일도 일단 다 열어 본 뒤 필터합니다
이 테이블은 created_at 으로 파티셔닝되어 있지 않아서 — 실무에서 흔한 상황입니다 — 4번 단계에서 사실상 모든 파일이 풀스캔됩니다. 이론적으로는 Parquet의 row group 프루닝이 작동해야 하지만, footer를 읽기 위해 모든 파일을 일단 열어야 한다는 점이 스캔 비용의 결정적 요인입니다.
Iceberg — manifest로 파일을 가려내고 건너뛴다
Apache Iceberg (2017, Netflix). 오브젝트 스토리지 위에서 Hive의 한계를 정조준해 만들어진 포맷.
Iceberg에서 테이블은 명시적으로 추적된 파일 집합입니다. S3 위에 3-Layer 메타데이터가 함께 살고 있습니다.
Glue → metadata.json → Snapshot → Manifest List → Manifest File → Data Files
참고: 메타데이터 계층 구조
각 Manifest File은 자기가 가리키는 데이터 파일들의 컬럼별 min/max, null 수, row 수를 모두 가지고 있습니다. Athena는 쿼리 플래닝 단계에서 이 통계만 보고 어떤 파일을 열지 결정합니다 — S3 LIST가 필요 없습니다.
단계별로 검색 공간이 어떻게 좁혀지는지 개념적으로 보면 다음과 같습니다.
현재 스냅샷 1개 선택
스냅샷이 가리키는 manifest들 중 partition summary가 조건에 맞는 것만 살아남음
살아남은 manifest의 데이터 파일들 중 컬럼 min/max가 조건에 맞는 것만 살아남음
그 일부 파일만 실제로 열어 스캔 → 위 측정에서는 40 MB (Hive는 같은 조건에서 5,164 MB)
단계마다 검색 공간이 한 자릿수 이상씩 줄어드는 구조입니다.
이것만 기억하세요
Hive는 파티션으로 후보 경로를 좁힌 뒤 남은 파일을 확인하고 Iceberg는 manifest와 파일 통계를 이용해 후보 파일을 더 앞단에서 줄인다.
이 내용이 이후 모든 벤치마크의 작동 원리입니다.
분석가 입장: Iceberg 테이블에서는 WHERE 절이 단순한 “필터”가 아니라 “어떤 파일을 열지 결정하는 힌트”입니다. 좁게 줄수록 빨라집니다.
데이터 엔지니어 입장: Hive에서 같은 효과를 내려면 적절한 파티션 키를 미리 설계 해야 합니다. 그것도 분석가가 그 파티션 컬럼을 정확히 WHERE에 써줘야만 효과가 납니다. Iceberg는 사용자가 파티션 컬럼을 직접 WHERE에 쓰지 않아도, partition spec과 파일 단위 컬럼 통계를 이용해 프루닝할 수 있습니다. 다만 효과는 데이터 클러스터링과 metrics 설정에 따라 달라집니다.— 운영 부담이 줄어드는 첫 번째 지점입니다.
다만 위는 단일 테이블·단순 WHERE의 이상적인 케이스입니다. 실제 운영 쿼리는 보통 더 복잡합니다. 다음 섹션에서 실제 분석 쿼리로 넘어갑니다.
3. 실제 분석 쿼리 — DPD 주별 추이
DPD란 무엇인가요
DPD(Days Past Due)는 사전에 약속된 정산 일자보다 실제 이행이 며칠 지연되었는지를 나타내는 지표입니다. 저희는 매주 활성 평가 건의 DPD를 버킷별 (CURRENT / 1-30 / 31-60 / 61-90 / 91-180 / 180+)로 집계해 평가 결과의 후행 검증 추세를 봅니다. 신용·리스크 분석의 핵심 모니터링 지표 중 하나입니다.
쿼리는 두 테이블을 조인합니다.
assessment — 평가 마스터 (수백만 row)
outcome_event — 각 평가 건의 시간별 정산 이벤트 (수억 row, 이 글의 핵심 테이블)
조인 후 주간 스냅샷마다 가장 오래된 미해결 이벤트의 만기 일자를 찾아 DPD를 산출합니다. 분석가가 가장 흔히 작성하는 패턴은 다음 두 가지입니다.
부분 푸시다운 (BAD) vs 완전 푸시다운 (GOOD)
부분 푸시다운: WHERE 조건을 driving 테이블에만 거는 패턴
WITH loan_base AS (
SELECT loan_id, disburse_dt
FROM assessment
WHERE disburse_dt >= DATE '2026-04-01' -- ← assessment에만 시간 조건
AND disburse_dt <= DATE '2026-06-22'
),
schedule AS (
SELECT loan_id, due_dt, close_dt
FROM outcome_event -- ← 시간 조건 없음. 수억 row 전체.
)
SELECT ... FROM loan_base JOIN schedule ...완전 푸시다운: WHERE 조건을 조인되는 모든 테이블에 동등하게 거는 패턴
WITH loan_base AS (
SELECT loan_id, disburse_dt
FROM assessment
WHERE disburse_dt >= DATE '2026-04-01'
AND disburse_dt <= DATE '2026-06-22'
),
schedule AS (
SELECT loan_id, due_dt, close_dt
FROM outcome_event
WHERE due_dt >= DATE '2026-03-01' -- ← outcome_event에도 시간 조건!
AND due_dt <= DATE '2026-06-22'
)
SELECT ... FROM loan_base JOIN schedule ...논리적으로 두 쿼리는 같은 결과를 냅니다. outcome_event.due_dt가 위 범위 밖이면 어차피 join에서 매칭되지 않기 때문입니다. 하지만 옵티마이저 입장에서는 천지차이입니다. 완전 푸시다운에서는 outcome_event 도 manifest 프루닝에 들어가, 수억 row 중 필요한 구간만 읽고 끝납니다.
측정 매트릭스
세 개의 조회 기간(1년 / 3개월 / 1개월) × 두 패턴(BAD / GOOD) × 두 포맷(Iceberg / Hive) = 12개 측정을 같은 Athena 워크로드 환경에서 돌렸습니다.
결과 — Iceberg vs Hive 절감률
같은 패턴 안에서 Hive 대비 Iceberg의 스캔 절감률:
핵심 패턴이 두 줄로 정리됩니다.
부분 푸시다운에서는 조회 기간을 좁혀도 Iceberg 우위가 ~30%에서 멈춥니다. 큰 테이블(outcome_event)에 필터 조건이 없어서 그쪽에서는 manifest 프루닝을 못 하기 때문입니다. 30%라는 한계는 assessment 프루닝만의 기여입니다.
완전 푸시다운에서는 조회 기간이 좁아질수록 Iceberg 우위가 커집니다. 양쪽 테이블 모두에서 manifest 프루닝이 작동하고, 두 축이 곱셈으로 작용합니다.
같은 Iceberg 테이블에서 SQL만 바꿔도 절반 이하
같은 Iceberg 테이블에서 BAD → GOOD으로 SQL만 바꿨을 때 스캔 절감률:
실질적인 비용 절감은 포맷 그 자체가 아닌, 올바른 SQL과 결합했을 때 완성됩니다
분석가 관점에서 이 결과는 매우 실용적입니다. 오늘 작성하는 쿼리에서 outcome_event 같은 큰 테이블에도 시간 조건을 거는 것만으로 같은 Iceberg 테이블에서 비용이 절반 이하로 떨어집니다. 코드 한 줄 추가의 ROI가 이렇게 큰 경우는 흔하지 않습니다.
Hive는 다른 양상 — 더 정성껏 써도 손해
같은 변경을 Hive에 적용하면 정반대 결과가 나옵니다.
조회 기간 | Hive 스캔 변화 |
|---|---|
1년 | +18% (증가) |
3개월 | +14% (증가) |
1개월 | +11% (증가) |
Hive는 추가 필터 조건을 파일 프루닝에 못 쓰고, 모든 row를 읽으면서 조건 평가만 더 하느라 오히려 스캔이 늘어납니다. 적어도 이 워크로드에서는 Hive-style table에 predicate를 더 명시적으로 넣어도 scan cost 절감으로 이어지지 않았습니다. 오히려 일부 케이스에서는 측정상 스캔량이 증가했습니다.
예상과 달랐지만, 재측정해도 결과는 같았습니다.
4. 부분 마이그레이션의 함정
도입 검토 단계에서 자주 나온 또 다른 질문입니다.
“전체 테이블을 한 번에 옮길 순 없다. 일부만 옮기면 그만큼 효과를 볼 수 있나?”
저희 환경에는 Iceberg 테이블 350여 개와 Hive 테이블 다수가 공존하므로, 두 포맷이 같은 쿼리에서 조인되는 시나리오가 자주 발생합니다. 핵심 두 테이블의 포맷 조합을 4가지로 두고 같은 DPD 쿼리를 돌렸습니다. (H = Hive, I = Iceberg, 앞이 assessment, 뒤가 outcome_event)
3개월 GOOD 패턴 결과
이 그래프가 마이그레이션 전략에 시사하는 바가 큽니다.
IH(작은 테이블만 Iceberg)는 HH(전부 Hive)와 거의 동일한 비용입니다. 작은 테이블을 Iceberg로 옮긴 노력이 거의 회수되지 않습니다.
반면 HI(큰 테이블만 Iceberg)는 II와 32% 격차만 보입니다. 마이그레이션 노력의 70% 이상이 회수됩니다.
함정이 더 깊어지는 지점 — 1년 조회 기간
조회 기간을 1년으로 늘리면 IH의 페널티가 더 폭증합니다.
시나리오 | 1년 GOOD vs II | 3개월 GOOD vs II |
|---|---|---|
IH (작은 테이블만 Iceberg) | +90% | +183% |
HI (큰 테이블만 Iceberg) | +29% | +32% |
마이그레이션 우선순위에 대한 답이 명확해집니다: 큰 테이블부터. 작은 테이블만 먼저 옮기면 비용 절감의 대부분을 놓칩니다.
이 발견은 직관에 부합하지만 — “큰 테이블이 중요하다” — 그 격차의 크기는 측정 전에는 예상하지 못했습니다. outcome_event 가 Hive면 manifest 프루닝 자체가 불가능 하므로 풀스캔으로 돌아가고, 그 비용이 전체를 압도합니다.
5. Spark에서는 어떨까 — 그리고 의외의 결과
Athena에서의 결과가 엔진 특성에 종속된 것은 아닌지 검증하기 위해, 같은 12개 시나리오를 PySpark에서 재측정했습니다. Livy /batches (cluster mode), Iceberg runtime 1.10.0, GlueCatalog 환경입니다.
Spark은 Athena와 달리 쿼리별 스캔량을 직접 노출하지 않으므로 wall-clock 시간만 비교 합니다. 결과 row 수는 Athena와 정확히 일치하는 것으로 확인했습니다.
큰 워크로드에서는 시간 차이도 벌어진다
조회 기간 | All-Hive (s) | All-Iceberg (s) | Iceberg 우열 |
|---|---|---|---|
1년 | 65.74 | 39.42 | 40% ↓ (빠름) |
3개월 | 11.53 | 13.60 | +18% (느림) |
1개월 | 8.10 | 10.07 | +24% (느림) |
작은 워크로드에서 Iceberg는 시간상 살짝 손해를 봅니다. 매니페스트 플래닝 오버헤드 때문입니다. 하지만 워크로드가 커지면 Iceberg의 시간 차이가 벌어집니다. 1년 데이터에서는 40% 빨라집니다.
“Iceberg는 비용은 절감되는데 속도는 약간 느릴 수 있다” 는 통념은 작은 쿼리에 한정된 이야기입니다. 큰 분석 쿼리에서는 속도까지 같이 빨라집니다.
반직관적 발견 — Spark Hive 1년 GOOD = 3배 느려짐
Spark에서 가장 놀라웠던 결과는 별도의 측정 케이스에서 나왔습니다. Hive 테이블에 BAD → GOOD 으로 추가 필터를 넣었을 때, 1년 조회 기간에서:
엔진 | 1년 BAD (s) | 1년 GOOD (s) | 변화 |
|---|---|---|---|
Athena Hive | 13.76 | 6.71 | −51% (빨라짐) |
Spark Hive | 65.74 | 195.68 | +197% (3배 느려짐) ❌ |
같은 SQL인데 엔진에 따라 정반대 반응이 나옵니다. 분석해 본 결과:
Athena 옵티마이저는 Hive에서도 Parquet row group skipping과 적극적인 분할(split)을 통해 추가 predicate를 시간 단축으로 변환합니다.
Spark은 동일한 워크로드에서 추가 predicate 평가가 모든 row에 대해 늘어나면서 실행 시간이 폭증합니다. 1년이라는 넓은 schedule filter(16개월) 자체가 프루닝 여지가 작아, manifest 프루닝 보상은 거의 없고 비용만 늘었습니다.
시사점: “predicate placement는 Athena에서 더 안전한 최적화 패턴이다.” Spark에서는 워크로드와 데이터 크기에 따라 역효과가 날 수 있습니다.
이런 엔진별 차이는 “Iceberg를 쓰면 다 잘 풀린다” 같은 일반론으로는 보이지 않습니다. 저희가 두 엔진에서 같은 매트릭스를 돌려본 이유가 바로 이런 디테일을 잡아내기 위해서였습니다.
6. Iceberg 포맷이 제공하고, Athena/Spark 조합에서 우리가 체감한 운영 이점
이 글의 메인 메시지는 “이론이 운영 데이터에서 실제로 발현된다” 였고, 측정은 비용과 속도에 집중했습니다. 하지만 데이터 엔지니어 관점에서 도입을 검토한다면 운영 측면의 이점도 같이 보아야 합니다. 저희가 도입하면서 실제로 체감한 항목을 짧게 정리합니다.
영역 | Hive | Iceberg | 우리 팀이 느낀 차이 |
|---|---|---|---|
새 데이터 추가 | MSCK REPAIR / ADD PARTITION 필요 | INSERT INTO 만으로 즉시 가시화 | 파이프라인에서 파티션 관리 코드 사라짐 |
ACID | 부분 쓰기 노출 가능 | snapshot isolation, atomic commit | 동시 쓰기 시 데이터 불일치 우려 제거 |
스키마 진화 | 컬럼 rename·type 변경 시 데이터 재작성 | 메타데이터-only (rename / add / drop / reorder) | 다운스트림 영향 없이 컬럼 정리 가능 |
Time travel | 미지원 | FOR TIMESTAMP AS OF / FOR VERSION AS OF | 데이터 사고 시 snapshot 되돌리기로 즉시 복구 |
Row-level mutation | INSERT 만. UPDATE는 수동 재작성 | 진짜 UPDATE / DELETE / MERGE | CDC 파이프라인 코드가 훨씬 단순해짐 |
유지보수 | 없음(이점도 없음) | expire_snapshots / rewrite_manifests 정기 실행 필요 | 새 운영 부담. 하지만 자동화 가능 |
(단, UPDATE/DELETE/MERGE의 실제 동작 방식은 엔진별 지원 범위와 table format version에 따라 달라집니다.)
마지막 행 — expire_snapshots / rewrite_manifests — 는 양면적입니다. 새로운 운영 부담이긴 하지만, 저희는 Airflow에서 주간 자동 실행으로 관리하고 있어 실제 운영 오버헤드는 크지 않습니다. 그리고 그 비용으로 위의 다섯 가지 이점을 얻습니다.
참고: Apache Iceberg 테이블 운영 실전기: 스냅샷 관리부터 Compaction까지
7. 우리가 미리 알았으면 좋았을 것들
마이그레이션을 진행하면서 시행착오로 얻은 교훈을 정리합니다. 같은 길을 가는 팀에 도움이 됐으면 합니다.
① 큰 테이블부터 옮기세요. 작은 테이블 100개를 옮기는 것보다 큰 테이블 한 개를 옮기는 것이 비용 절감 효과가 훨씬 큽니다. 위 Mixed format 측정이 그 증거입니다. 저희는 초반에 “리스크가 낮으니까” 라는 이유로 작은 테이블부터 옮겼고, 절감 효과가 한참 동안 보이지 않았습니다.
② 분석가에게 SQL 패턴 가이드를 함께 배포하세요. 포맷만 옮긴다고 끝이 아닙니다. “모든 조인 테이블의 시간 컬럼에 동일한 시간 조건을 거세요” — 이 한 줄의 가이드로 같은 Iceberg 테이블에서 절감이 2~3배 추가됩니다. 포맷 자체보다 사용 패턴이 더 큰 변수입니다.
③ Iceberg의 플래닝 오버헤드를 인정하세요. 작은 쿼리(스캔량 100MB 이하)에서는 Iceberg가 시간상 느릴 수 있습니다. 이게 “버그”가 아니라 manifest 읽기 비용입니다. 대시보드용 짧은 쿼리만 도는 워크로드라면 이 트레이드오프를 인지하고 도입해야 합니다. 저희 환경에서는 큰 분석 쿼리가 비용의 대부분을 차지하므로 순 이득이었습니다.
④ Hive와 Iceberg가 섞이는 쿼리를 모니터링하세요. 부분 마이그레이션 중에는 두 포맷이 같은 쿼리에서 조인되는 케이스가 발생합니다. 위에서 본 IH 패턴(작은 테이블만 Iceberg + 큰 테이블 Hive)은 거의 모든 절감 효과를 잃습니다. 마이그레이션 진행 중에는 이런 조합의 쿼리를 별도로 추적하면서 우선순위를 조정해야 합니다.
⑤ Spark과 Athena의 옵티마이저가 같다고 가정하지 마세요. 위 1년 GOOD 케이스 처럼, 한 엔진에서는 명백한 최적화가 다른 엔진에서는 역효과가 날 수 있습니다. 두 엔진을 모두 쓰는 환경이라면 핵심 쿼리는 양쪽에서 확인하고 가이드를 분리해야 합니다.
8. 두 독자에게 드리는 결론
분석가에게 — 오늘 바꿀 SQL 패턴
조인되는 모든 테이블에 동일한 시간 조건을 걸어주세요. 같은 Iceberg 테이블에서 비용이 절반 이하로 떨어집니다. 코드 한 줄 추가의 ROI가 비교가 안 됩니다.
WHERE 절을 좁히는 것 자체가 비용 절감입니다. Iceberg에서는 WHERE가 “필터”가 아니라 “어떤 파일을 열지 결정하는 힌트”입니다. 분석 자유도를 해치지 않는 한 가능한 한 좁히세요.
작은 쿼리에서 Iceberg가 살짝 느리다면 정상입니다. 매니페스트 플래닝 오버헤드 때문이고, 큰 분석 쿼리에서는 속도까지 같이 빨라지면서 영향이 축소 됩니다.
쿼리에서 어떤 테이블이 Iceberg인지 모르겠다면, 카탈로그에서 table_type 속성을 확인하거나 데이터 엔지니어에게 물어보세요. Iceberg면 위 패턴이 적용받지만 Hive면 차이가 없을 수 있습니다.
데이터 엔지니어에게 — Iceberg 도입 검토 시
비용 절감은 일관됩니다. 단순 SELECT에서 100배, 복잡한 DPD 쿼리에서 1.4×~3.4×. 모든 벤치마킹에서 Iceberg가 스캔량을 줄였습니다.
마이그레이션 우선순위는 무조건 큰 테이블부터. 작은 테이블만 옮기면 절감 효과가 거의 사라집니다. IH(작은 테이블만 Iceberg) ≈ HH(전부 Hive) 입니다.
포맷만 옮긴다고 끝이 아닙니다. 분석가에게 “모든 조인 테이블에 시간 조건” 패턴을 함께 배포해야 완전 푸시다운의 절감(3.15×~3.45×)이 실현됩니다.
운영 이점은 비용 절감과 별개로도 큽니다. ACID, 스키마 진화, time travel, row-level mutation, 자동 파티션 관리 — 이 다섯이 도입 후 가장 체감되는 일상적 생산성 향상이었습니다.
엔진별 옵티마이저 차이를 측정으로 검증하세요. Athena와 Spark은 같은 SQL에 다르게 반응합니다. 도입 전 핵심 쿼리는 양쪽에서 직접 측정하길 권합니다.
측정 환경
Athena: workgroup jupyterhub, region ap-south-1, 과금 $5/TB scan
Spark: PySpark via Livy, cluster mode, Iceberg runtime 1.10.0, GlueCatalog
데이터: 실제 운영 중인 CDC 미러 테이블 (사내 보안 정책으로 테이블·컬럼명은 익명화)
측정일: 2026-06-23 ~ 2026-06-26
재현성: Warm-up은 3회 평균, DPD 쿼리 매트릭스는 1회 측정 (실행 시간은 ±10% 편차가 있으나 스캔량은 결정적)
결과 정합성: Iceberg/Hive 양쪽 모든 시나리오에서 결과 row 수가 0.001% 수준으로 일치 (CDC lag로 인한 미세 차이)
이 글에서 측정한 모든 결과는 어피닛의 실제 운영 데이터에서 얻은 수치입니다.
“이론이 실무에서 어디까지 발현되고, 어디서 어긋나는지” 를 정직하게 기록하는 것이 저희 데이터 엔지니어링 팀의 일하는 방식이고, 같은 의사결정을 앞두고 있는 다른 팀에도 이 기록이 의미 있게 쓰이기를 바랍니다.
어피닛 데이터 엔지니어링 팀