Skip to main content

이 문서에서 다루는 내용

Databricks 플랫폼에서 쿼리, 파이프라인, ML 워크로드의 성능을 극대화하는 방법을 다룹니다. Delta Lake 데이터 레이아웃부터 Spark 쿼리 튜닝, SQL Warehouse 최적화, 파이프라인 처리량 개선, ML/AI 지연시간 최적화까지 실전 트러블슈팅 가이드를 제공합니다.

1. Delta Lake 성능 최적화

1.1 Liquid Clustering 키 선택 전략

Liquid Clustering은 기존의 파티셔닝과 Z-ORDER를 대체하는 현대적인 데이터 레이아웃 기술입니다. 올바른 키 선택이 성능을 좌우합니다. 키 선택 의사결정 매트릭스
고려 요소좋은 키나쁜 키
쿼리 필터 빈도WHERE절에 자주 등장거의 필터링되지 않음
카디널리티고 (수천수백만)극저 (boolean, 2-3값) 또는 극고 (UUID)
상관관계다른 키와 독립적다른 키와 높은 상관 (둘 다 선택 불필요)
데이터 타입Date, String, IntegerArray, Map, Struct
키 개수1~4개5개 이상 (최대 4개 제한)
-- 사례 1: 이커머스 트랜잭션 테이블
-- 쿼리 패턴: 날짜 범위 + 지역 필터가 대부분
ALTER TABLE sales.silver.transactions
CLUSTER BY (transaction_date, region);

-- 사례 2: IoT 센서 데이터
-- 쿼리 패턴: 디바이스별 + 시간 범위 조회
ALTER TABLE iot.silver.sensor_readings
CLUSTER BY (device_id, event_timestamp);

-- 사례 3: 쿼리 패턴이 자주 변경되는 테이블
-- Databricks가 자동으로 최적 키를 분석하여 결정
ALTER TABLE analytics.gold.user_behavior
CLUSTER BY AUTO;
기존 테이블 마이그레이션 가이드
현재 방식마이그레이션 전략
PARTITIONED BY (date)CLUSTER BY (date) — 파티션 키를 클러스터링 키로
ZORDER BY (col_a, col_b)CLUSTER BY (col_a, col_b) — Z-ORDER 키를 그대로
파티션 + Z-ORDERCLUSTER BY (partition_col, zorder_col) — 둘 다 포함
없음 (최적화 안 함)CLUSTER BY AUTO — 자동 분석 후 적용
💡 핵심 장점: Liquid Clustering은 키를 변경해도 기존 데이터를 즉시 다시 쓸 필요가 없습니다. 이후 OPTIMIZE 실행 시 점진적으로 새 키에 맞게 재배치됩니다.

1.2 파일 사이즈 최적화

Delta Lake의 최적 파일 크기는 128MB ~ 1GB 입니다. 이 범위를 벗어나면 성능이 저하됩니다.
문제원인증상해결 방법
Small File 문제잦은 스트리밍 쓰기, 작은 배치파일 수 과다, 메타데이터 오버헤드OPTIMIZE 실행
Large File 문제과도한 OPTIMIZE, 큰 배치프루닝 효과 감소, 메모리 압박파일 크기 상한 설정
-- Small File 진단: 파일 수와 평균 크기 확인
DESCRIBE DETAIL catalog.schema.table_name;
-- numFiles, sizeInBytes를 확인하여 평균 파일 크기 계산
-- 평균 < 32MB면 OPTIMIZE 필요

-- OPTIMIZE로 파일 병합
OPTIMIZE catalog.schema.table_name;

-- 특정 파티션만 OPTIMIZE (대용량 테이블)
OPTIMIZE catalog.schema.table_name
WHERE event_date >= current_date() - INTERVAL 7 DAYS;
# 스트리밍 쓰기 시 파일 크기 제어
(df.writeStream
  .option("maxBytesPerTrigger", "100m")  # 트리거당 최대 100MB 읽기
  .option("maxFilesPerTrigger", "1000")   # 트리거당 최대 파일 수
  .trigger(processingTime="30 seconds")   # 30초 간격 → 적당한 파일 크기
  .table("catalog.schema.streaming_table")
)

1.3 통계 수집 및 Data Skipping

Data Skipping은 쿼리 실행 시 불필요한 파일을 자동으로 건너뛰는 기능입니다. 정확한 통계 정보가 필수적입니다.
-- Delta 통계 재수집 (Runtime 14.3 LTS+)
ANALYZE TABLE catalog.schema.table_name COMPUTE DELTA STATISTICS;

-- 특정 컬럼에 대한 통계 수집
ALTER TABLE catalog.schema.table_name
SET TBLPROPERTIES('delta.dataSkippingStatsColumns' = 'event_date, user_id, region');

-- 통계 수집 대상 컬럼 수 확인 (기본: 처음 32개 컬럼)
-- Unity Catalog 관리형 테이블은 Predictive Optimization이 자동으로 관리
기능동작 방식성능 효과
Min/Max 통계파일별 최소/최대값 기록WHERE절 조건으로 파일 단위 스킵
Null Count파일별 NULL 수 기록IS NOT NULL 필터 최적화
Liquid Clustering관련 데이터를 같은 파일에 배치Data Skipping 효과 극대화
ANALYZE TABLE통계 강제 재수집테이블 속성 변경 후 반드시 실행

2. Liquid Clustering 심층 가이드

2.1 Liquid Clustering vs Z-ORDER vs 파티셔닝

비교 항목파티셔닝Z-ORDERLiquid Clustering
적용 시점테이블 생성 시 고정OPTIMIZE 시 수동언제든 변경 가능
키 변경불가 (재생성 필요)변경 가능 (전체 재정렬)변경 가능 (점진적)
증분 적용N/A불가 (전체 테이블)✅ 새 데이터만 정렬
자동 최적화✅ Predictive Optimization
Small File 문제고카디널리티 시 심각없음없음
쓰기 성능 영향없음OPTIMIZE 시 높은 비용최소 (증분)
참고 마이그레이션 권장: 신규 테이블은 Liquid Clustering을 기본으로 사용하세요. 기존 파티셔닝/Z-ORDER 테이블은 점진적으로 전환하되, CLUSTER BY AUTO 를 먼저 적용하여 Databricks가 최적 키를 자동 분석하게 하는 것이 안전합니다.

2.2 Liquid Clustering 모니터링

-- 클러스터링 상태 확인
DESCRIBE DETAIL catalog.schema.table_name;
-- clusteringColumns: 현재 클러스터링 키
-- numFiles: 파일 수
-- sizeInBytes: 총 크기

-- 클러스터링 효과 측정: 동일 쿼리의 스캔량 비교
-- 클러스터링 적용 전
EXPLAIN FORMATTED
SELECT * FROM catalog.schema.table_name
WHERE event_date = '2026-03-01' AND region = 'KR';
-- "number of files read" 값을 기록

-- OPTIMIZE 실행 (클러스터링 적용)
OPTIMIZE catalog.schema.table_name;

-- 클러스터링 적용 후 동일 쿼리 실행
-- "number of files read" 값이 줄어들었는지 확인

2.3 클러스터링 키 튜닝 사례

-- 사례: 로그 테이블에서 클러스터링 키 최적화
-- 초기 설정: 날짜만
ALTER TABLE logs.silver.app_events CLUSTER BY (event_date);

-- 문제: user_id로 필터링하는 쿼리가 많지만 여전히 풀 스캔
-- 개선: 날짜 + user_id 조합
ALTER TABLE logs.silver.app_events CLUSTER BY (event_date, user_id);

-- OPTIMIZE 실행 (새 키에 맞게 재배치 시작)
OPTIMIZE logs.silver.app_events;

-- 결과: user_id 필터 쿼리의 스캔량 80% 감소

3. VACUUM 전략

3.1 VACUUM 기본 동작

VACUUM은 더 이상 Delta 트랜잭션 로그에서 참조되지 않는 오래된 파일을 삭제합니다.
-- 기본 VACUUM (7일 보존)
VACUUM catalog.schema.table_name RETAIN 168 HOURS;

-- 보존 기간 확인
DESCRIBE DETAIL catalog.schema.table_name;
-- 'delta.deletedFileRetentionDuration' 속성 확인

-- DRY RUN: 삭제 대상 파일 목록만 확인 (실제 삭제 안 함)
VACUUM catalog.schema.table_name RETAIN 168 HOURS DRY RUN;

3.2 보존 기간 전략

테이블 유형권장 보존 기간이유
실시간 스트리밍24~48시간파일 생성 빈번, 스토리지 비용 억제
일일 배치7일 (기본값)Time Travel 활용 여유
규제 데이터 (금융)30일감사/롤백 요구사항
ML Feature 테이블7일재학습 시 이전 버전 필요 가능
임시/실험 테이블24시간스토리지 절약 우선
-- 테이블별 보존 기간 설정
ALTER TABLE catalog.schema.streaming_events
SET TBLPROPERTIES ('delta.deletedFileRetentionDuration' = 'interval 48 hours');

ALTER TABLE catalog.schema.financial_transactions
SET TBLPROPERTIES ('delta.deletedFileRetentionDuration' = 'interval 30 days');

-- 로그 보존 기간 (트랜잭션 로그 자체)
ALTER TABLE catalog.schema.table_name
SET TBLPROPERTIES ('delta.logRetentionDuration' = 'interval 60 days');
주의 VACUUM 후 Time Travel 불가: VACUUM으로 삭제된 파일에 해당하는 버전은 Time Travel로 접근할 수 없습니다. 규제 요건이 있는 테이블은 보존 기간을 충분히 길게 설정하세요.

3.3 VACUUM 자동화

-- 방법 1: Predictive Optimization (권장)
-- Unity Catalog 관리형 테이블에 대해 자동 VACUUM
ALTER CATALOG my_catalog ENABLE PREDICTIVE OPTIMIZATION;

-- 방법 2: 스케줄 Job으로 수동 자동화
-- 매일 실행하는 VACUUM Job (노트북에서)
# VACUUM 자동화 노트북 예시
tables_to_vacuum = [
    ("catalog.schema.table1", 168),   # 7일 보존
    ("catalog.schema.table2", 48),    # 2일 보존
    ("catalog.schema.table3", 720),   # 30일 보존
]

for table_name, retain_hours in tables_to_vacuum:
    try:
        spark.sql(f"VACUUM {table_name} RETAIN {retain_hours} HOURS")
        print(f"✅ VACUUM 완료: {table_name}")
    except Exception as e:
        print(f"❌ VACUUM 실패: {table_name} - {e}")

4. Deletion Vectors 성능 영향

4.1 Deletion Vectors란?

Deletion Vectors는 DELETE/UPDATE/MERGE 시 파일을 즉시 다시 쓰지 않고, 삭제된 행의 비트맵을 별도로 기록하는 기술입니다.
항목기존 방식 (Copy-on-Write)Deletion Vectors
DELETE 속도전체 파일 재작성비트맵만 기록 (10~100x 빠름)
스토리지 사용즉시 정리삭제 행이 파일에 남음 (OPTIMIZE 시 정리)
읽기 성능최적약간의 오버헤드 (비트맵 확인)
활성화기본 비활성화 (레거시)Runtime 14.0+에서 기본 활성화
-- Deletion Vectors 상태 확인
DESCRIBE DETAIL catalog.schema.table_name;
-- 'delta.enableDeletionVectors' = 'true' 확인

-- Deletion Vectors 활성화 (레거시 테이블)
ALTER TABLE catalog.schema.table_name
SET TBLPROPERTIES ('delta.enableDeletionVectors' = true);

-- Deletion Vectors 누적 시 성능 저하 해소
-- OPTIMIZE가 Deletion Vectors를 물리적으로 정리
OPTIMIZE catalog.schema.table_name;

4.2 Deletion Vectors 모니터링

-- Deletion Vectors가 누적된 파일 비율 확인
-- DESCRIBE DETAIL의 numFiles와 실제 유효 행 수 비교

-- 대량 DELETE 후 읽기 성능이 저하되면 OPTIMIZE 실행
-- 일반적으로 삭제 비율이 10% 이상이면 OPTIMIZE 권장
참고 Deletion Vectors + MERGE 패턴: SCD Type 2 MERGE에서 Deletion Vectors가 큰 효과를 발휘합니다. 기존에 수십 분 걸리던 MERGE 작업이 수 분으로 단축됩니다. Predictive Optimization이 활성화되어 있으면 누적된 Deletion Vectors는 자동으로 정리됩니다.

5. Predictive Optimization 설정 및 모니터링

5.1 활성화 범위

-- 카탈로그 수준 활성화 (하위 모든 스키마/테이블에 적용)
ALTER CATALOG prod_sales ENABLE PREDICTIVE OPTIMIZATION;

-- 스키마 수준 활성화
ALTER SCHEMA prod_sales.gold ENABLE PREDICTIVE OPTIMIZATION;

-- 특정 스키마 비활성화 (예: 임시 데이터)
ALTER SCHEMA prod_sales.sandbox DISABLE PREDICTIVE OPTIMIZATION;

-- 비활성화한 객체의 하위 객체도 비활성화됨
-- 상위가 활성화되어도 하위에서 명시적으로 비활성화 가능

5.2 모니터링

-- Predictive Optimization 작업 이력 확인
SELECT
  table_name,
  operation_type,    -- OPTIMIZE, VACUUM, ANALYZE
  operation_status,  -- SUCCESSFUL, FAILED, SKIPPED
  operation_metrics, -- 처리한 파일 수, 크기 등
  timestamp
FROM system.storage.predictive_optimization_operations_history
WHERE timestamp >= current_date() - INTERVAL 7 DAYS
ORDER BY timestamp DESC;

-- 비용 확인 (Serverless Jobs SKU로 과금)
SELECT
  date_trunc('day', timestamp) AS day,
  operation_type,
  COUNT(*) AS num_operations,
  SUM(operation_metrics.dbus_consumed) AS total_dbus
FROM system.storage.predictive_optimization_operations_history
WHERE timestamp >= current_date() - INTERVAL 30 DAYS
GROUP BY 1, 2
ORDER BY 1 DESC;
Predictive Optimization 작업실행 조건효과
Auto-OPTIMIZESmall File 감지 시파일 병합, 읽기 성능 향상
Auto-VACUUM참조 없는 파일 감지 시스토리지 비용 절감
Auto-ANALYZE통계 불일치 감지 시쿼리 옵티마이저 정확도 향상
Auto-Compaction스트리밍 테이블 Small File실시간 파일 병합
참고 비용 대비 효과: Predictive Optimization의 비용은 일반적으로 수동 OPTIMIZE/VACUUM 실행 비용의 30~50%입니다. 자동 실행이므로 관리 인력 비용도 절감됩니다. 2024년 11월 이후 생성된 계정에는 기본 활성화되어 있습니다.

6. 파일 크기 최적화 상세

6.1 워크로드별 최적 파일 크기

워크로드권장 파일 크기설정 방법
대규모 ETL (TB 단위)512MB ~ 1GBspark.databricks.delta.optimizeWrite.fileSize = 536870912
대시보드/BI 쿼리128MB ~ 256MB기본값 유지
스트리밍 (초 단위)64MB ~ 128MBAuto-compaction + OPTIMIZE
ML Feature 테이블32MB ~ 64MB소규모 테이블, 빈번한 읽기
# 쓰기 시 파일 크기 제어
# Optimize Write: 자동으로 적절한 크기의 파일 생성
spark.conf.set("spark.databricks.delta.optimizeWrite.enabled", "true")

# 파일 크기 목표 설정 (바이트 단위)
spark.conf.set("spark.databricks.delta.optimizeWrite.fileSize", "134217728")  # 128MB

# Auto Compaction: 커밋 후 자동으로 Small File 병합
spark.conf.set("spark.databricks.delta.autoCompact.enabled", "true")
spark.conf.set("spark.databricks.delta.autoCompact.minNumFiles", "20")  # 20개 이상이면 병합

참고 링크