메인 콘텐츠로 건너뛰기
이 문서에서는 lazy materialization의 작동 방식과 이것이 ClickHouse의 전반적인 I/O 최적화 스택에 어떻게 포함되는지 설명합니다. 또한 lazy materialization이 쿼리 성능을 어떻게 향상시키는지 보여 주는 실제 예시를 소개합니다.
버전 25.4부터 사용 가능lazy materialization은 ClickHouse 버전 25.4에서 도입되었으며 기본적으로 활성화되어 있습니다.

개요

수년에 걸쳐 ClickHouse는 I/O를 과감하게 줄이기 위해 여러 계층의 최적화 기법을 도입해 왔습니다. 이러한 기법은 ClickHouse의 속도와 효율성을 뒷받침하는 기반입니다: 앞서 언급한 I/O 최적화는 읽어야 하는 데이터를 크게 줄일 수 있지만, 여전히 WHERE 절을 통과한 행의 모든 컬럼을 정렬, 집계, LIMIT 같은 작업을 수행하기 전에 로드해야 한다고 가정합니다. 하지만 일부 컬럼은 나중에야 필요하거나, 어떤 데이터는 WHERE 절을 통과하더라도 결국 전혀 필요하지 않다면 어떨까요? 이때 lazy materialization이 필요합니다. 이는 I/O 최적화 스택을 완성하는 별개의 개선 기법입니다:
  • 인덱싱은 PREWHERE와 함께 WHERE 절의 컬럼 필터와 일치하는 행만 처리되도록 보장합니다.
  • Lazy materialization은 이를 바탕으로, 쿼리 실행 계획에서 실제로 필요해질 때까지 컬럼 읽기를 미룹니다. 필터링 이후에도 다음 작업(예: 정렬)에 필요한 컬럼만 즉시 로드됩니다. 나머지 컬럼은 뒤로 미뤄지며, LIMIT 때문에 최종 결과를 만드는 데 필요한 만큼만, 즉 대개 일부만 읽으면 됩니다. 따라서 lazy materialization은 Top N 쿼리에서 특히 강력합니다. 최종 결과를 만들기 위해 특정 컬럼들(대개 크기가 큰 컬럼들)에서 소수의 행만 필요할 수 있기 때문입니다.

예시로 살펴보기

lazy materialization을 자세히 알아보려면 “ClickHouse gets lazier (and faster): Introducing lazy materialization” 블로그 게시물을 참고하시기를 강력히 권장합니다. 아래 예시는 앞서 언급한 블로그 게시물에서 가져온 내용을 여기에서 다시 소개한 것으로, lazy materialization을 통해 ClickHouse 쿼리 실행 시간이 219초에서 단 139밀리초로 단축될 수 있음을 보여줍니다(1576배 향상). 인덱싱과 PREWHERE의 이점을 활용하려면 쿼리에 필터가 있어야 합니다. 인덱싱에는 프라이머리 키(primary key) 컬럼에 대한 필터가 필요하고, PREWHERE에는 임의의 컬럼에 대한 필터가 필요합니다. 그 위에 lazy materialization을 자연스럽게 적용할 수 있지만, 앞서 언급한 다른 최적화와는 달리 컬럼 필터가 전혀 없는 쿼리도 가속할 수 있습니다. 다음 예시 쿼리는 날짜, 제품, 평점, 검증 상태와 관계없이 도움이 되었다는 투표 수가 가장 많은 Amazon 리뷰를 찾고, 제목, 헤드라인, 전체 텍스트와 함께 상위 3개를 반환합니다. 먼저 lazy materialization을 비활성화한 상태에서(query_plan_optimize_lazy_materialization 사용), 쿼리를 콜드 파일 시스템 캐시 상태로 실행합니다:
Query
Response
다음으로 쿼리를 다시 실행합니다(이번에도 콜드 파일 시스템 캐시로 실행). 이번에는 lazy materialization을 활성화한 상태입니다:
Query
일반적으로는 query_plan_optimize_lazy_materialization = true를 명시적으로 설정하지 않아도 lazy materialization의 이점을 얻을 수 있습니다. 기본적으로 활성화되어 있습니다.
Response
lazy materialization을 끈 경우와 켠 경우의 성능 차이를 살펴보겠습니다:

쿼리 실행 계획에서 lazy materialization을 확인하는 방법

EXPLAIN 절을 사용해 쿼리의 논리 실행 계획을 살펴보면, 앞선 쿼리에서 lazy materialization이 사용되었는지 확인할 수 있습니다:
연산자 계획은 아래에서 위로 읽을 수 있으며, ClickHouse가 정렬과 제한을 적용한 후에야 3개의 큰 String 컬럼을 읽는다는 점을 확인할 수 있습니다.
마지막 수정일 2026년 7월 1일