ClickHouse가 더 게을러지고 더 빨라집니다 - 지연 로딩 최적화 도입

2 weeks ago 11

  • ClickHouse가 새로운 최적화 기법인 lazy materialization을 도입하여 Top N 쿼리 성능을 최대 1,500배까지 향상시킴
  • 필요할 때만 컬럼 데이터를 읽는 전략을 통해 디스크 I/O를 최소화함
  • 기존의 컬럼 스토리지, 인덱스, PREWHERE 기법과 함께 계층적 I/O 최적화 스택을 구성
  • 쿼리 실행 계획에 따라 컬럼 데이터를 지연 로딩하여, 특히 LIMIT 절이 있는 쿼리에서 큰 효과를 발휘함
  • 기본 설정으로 활성화됨으로써, 코드 변경 없이 성능 향상을 얻을 수 있음

ClickHouse의 지연된 최적화 전략: Lazy Materialization

핵심 개념

  • ClickHouse는 불필요한 데이터를 읽지 않음으로써 성능을 극대화
  • lazy materialization은 쿼리 실행 중 실제로 필요한 시점에만 컬럼 데이터를 로딩하는 방식
  • 기존의 I/O 최적화 기법들과 독립적으로 작동하면서 상호 보완적인 성능 향상을 제공함

기존 I/O 최적화 기술

  • 컬럼 기반 저장소: 필요한 컬럼만 읽음
  • Sparse Index / Skipping Index / Projections: 필터링된 조건에 맞는 granule만 읽음
  • PREWHERE: 비인덱스 컬럼을 조기 필터링
  • Query Condition Cache: 반복 쿼리의 결과를 캐시해 동일 granule 재처리를 피함

Lazy Materialization의 원리

  • 기존 기술이 필터링을 통한 I/O 감소에 집중했다면, lazy materialization은 연산 시점까지 읽기를 연기
  • 쿼리의 다음 단계가 필요한 컬럼만 즉시 읽고, 나머지는 LIMIT 이후에 필요할 때 읽음
  • 특히 Top N 쿼리에서 일부 컬럼만 조회되므로, 대용량 텍스트 컬럼 등을 거의 읽지 않음

컬럼 독립 저장 방식이기 때문에 가능한 최적화이며, row-based DB에선 불가능한 접근


실제 예시: Amazon 리뷰 데이터셋

  • 150M rows, 70GB 비압축, 30GB 압축

  • Top N 쿼리 예시:

    SELECT helpful_votes FROM amazon.amazon_reviews ORDER BY helpful_votes DESC LIMIT 3;
    • 실행 시간: 0.07초
    • 컬럼 단독 조회로 고속 처리
  • 대용량 텍스트 컬럼 조회 예시:

    SELECT review_body FROM amazon.amazon_reviews FORMAT Null;
    • 실행 시간: 176초
    • 단일 컬럼이지만 56GB로 디스크 I/O 병목 발생

최적화 계층 적용별 성능 비교

1. 최적화 없음 (Baseline)

  • 실행 시간: 219초
  • 처리량: 72GB, 150M rows
  • 모든 컬럼을 모두 읽고 정렬

2. Primary Key Index 적용

  • 실행 시간: 96초
  • 처리량: 28GB, 53M rows
  • PK 기반 granule 필터링으로 50% 이상 시간 절감

3. PREWHERE 추가

  • 실행 시간: 61초
  • 처리량: 16GB
  • 비인덱스 필터 조건도 적용하여 추가 I/O 감소

4. Lazy Materialization 활성화

  • 실행 시간: 0.18초
  • 처리량: 807MB
  • 최종적으로 필요한 3개 row만 큰 컬럼에서 로딩

총 1,200배 이상 성능 향상, 150배 이상 메모리 사용 감소


필터 없는 Top N 쿼리에도 유효

  • 필터 없는 전체 정렬 쿼리에서:

    SELECT helpful_votes, product_title, review_headline, review_body FROM amazon.amazon_reviews ORDER BY helpful_votes DESC LIMIT 3;
  • lazy materialization 전: 219초

  • lazy materialization 후: 0.139초

  • 1,576배 속도 향상, 40배 I/O 감소, 300배 메모리 사용 감소


실행 계획 확인

EXPLAIN actions = 1 SELECT helpful_votes, product_title, review_headline, review_body FROM amazon.amazon_reviews ORDER BY helpful_votes DESC LIMIT 3 SETTINGS query_plan_optimize_lazy_materialization = true;
  • 결과:
Lazily read columns: review_headline, review_body, product_title Limit Sorting ReadFromMergeTree
  • 정렬과 LIMIT 후에만 대용량 컬럼을 로딩

결론

  • ClickHouse의 I/O 최적화 스택 완성: Index → PREWHERE → Lazy Materialization
  • 코드 변경 없이, 쿼리 실행 방식만으로 성능 수백~수천 배 향상
  • 특히 Top N 패턴, 대용량 컬럼, LIMIT 쿼리에 이상적
  • 기본 설정으로 활성화되어 사용자가 따로 설정하지 않아도 자동 적용

같은 SQL, 같은 머신, 다른 결과
빠름 = 덜 읽음 = ClickHouse

Read Entire Article