-
Clickhouse Projections개발/기술 2025. 11. 7. 20:39
Projections
Projections | ClickHouse Docs
Page describing what projections are, how they can be used to improve query performance, and how they differ from materialized views.
clickhouse.com
Projection 은 클릭하우스에서 속도를 올리기 위한 기술중 하나다.
실질적으로 Projection 은 기존 테이블에 숨겨진 추가 테이블이라고 볼 수 있다. projection 은 기존 테이블과 행의 순서도 다르고 primary index 도 다르다. 데이터가 들어올 때마다 자동으로 그리고 점진적으로 aggregate values 들을 구해준다
Practically, a Projection can be thought of as an additional, hidden table to the original table. The projection can have a different row order, and therefore a different primary index, to that of the original table and it can automatically and incrementally pre-compute aggregate values
Projection 은 여러개의 행도 가지고 있고 삽입 시점에 미리 Aggregation 을 해준다는 점에서 Materialized Views 랑 비슷하다. 단 Materialized View 랑은 달리 기존 테이블 데이터를 주기적으로 싱크를 맞추고 있다는 점에서 다르다.
Original Table 에 대한 쿼리 요청이 들어오면 클릭하우스에서는 동일한 결과를 낼 수 있는 Projection 테이블을 선택하는데 로직은 아래와 같다.

25.5 버전부터 projection 에 두가지 방식중 하나를 선택할 수 있는데 기존처럼 모든 칼럼을 저장할지 아니면 sortingkey +_part_offset
을 같이 이용하는 방법이 있다. 후자의 경우 기존 테이블에서 데이터를 읽어오는 방식이기 때문에 용량을 차지하지는 않지만 I/O 리소스가 발생한다.
예시;
PK 가 아닌 칼럼에 대해서 필터링을 걸고 싶을때
SELECT tip_amount, trip_id, dateDiff('minutes', pickup_datetime, dropoff_datetime) AS trip_duration_min FROM nyc_taxi.trips WHERE tip_amount > 200 AND trip_duration_min > 0 ORDER BY tip_amount, trip_id ASC위의 쿼리에서는 trip_duration_min 칼럼에 대해서 조건문을 걸어주고 있는데 이게 PK 가 아니기 때문에 성능이 좋지 않다
자주쓰이는 쿼리라면 여기에 projection 을 걸어줄 수 있다. 새로운 테이블을 만든건 아니지만 dateDiff 함수를 사용할대 아래 프로젝션 로직을 사용하게 된다
ALTER TABLE nyc_taxi.trips_with_projection ADD PROJECTION prj_tip_amount ( SELECT * ORDER BY tip_amount, dateDiff('minutes', pickup_datetime, dropoff_datetime) ) ALTER TABLE nyc.trips_with_projection MATERIALIZE PROJECTION prj_tip_amountProjection 을 사용하고 나면 query_log 에 projection 을 사용했다고 나온다. 반복되는 쿼리 요청이 있다면 projection 사용해서 간편하게 처리해줄 수 있을듯하다
┌─query─────────────────────────────────────────────────────────────────────────┬─projections──────────────────────┐ │ SELECT ↴│ ['default.trips.prj_tip_amount'] │ │↳ tip_amount, ↴│ │ │↳ trip_id, ↴│ │ │↳ dateDiff('minutes', pickup_datetime, dropoff_datetime) AS trip_duration_min↴│ │ │↳FROM trips WHERE tip_amount > 200 AND trip_duration_min > 0 │ │ └───────────────────────────────────────────────────────────────────────────────┴──────────────────────────────────┘'개발 > 기술' 카테고리의 다른 글
Clickhouse Materialized views (0) 2025.11.07 Clickhouse Skip Index (0) 2025.11.07 Clickhouse JSON 칼럼 (0) 2025.10.27 클릭하우스 업데이트 빠르게 만들기 (0) 2025.10.03 클릭하우스 업데이트는 왜 느릴까? (0) 2025.09.13