공식 문서 (architecture.md, core-concepts, best-practices) 기반 학습 자료 개념 이해 → 실무 예제 → 빠른 참조 3단 구성
clickhouse-guide/
├── chapters/ ← 개념 학습 (1~11장)
├── examples/ ← 실무 도메인 예제 (E-commerce, IoT 등)
├── troubleshooting/ ← 실수 케이스 스터디 (12개 케이스)
└── cheatsheets/ ← 빠른 참조 (엔진, 타입, 버전 등)
chapters/ch01_clickhouse_overview.md (왜 쓰는가, 설계 철학)
↓
chapters/ch04_table_parts.md (파트 = 저장의 기본)
↓
chapters/ch07_primary_index.md (성능의 핵심)
↓
examples/01_ecommerce_orders.md (실제 예제로 이해)
chapters/ch09_insert_strategy.md
↓
cheatsheets/insert_strategy_flowchart.md
↓
examples/02_observability_logs.md (Async Insert 실전)
↓
examples/03_iot_sensors.md (시계열 코덱)
chapters/ch10_anti_patterns.md
↓
chapters/ch11_monitoring_troubleshooting.md
↓
cheatsheets/troubleshooting_queries.md
-
- OLAP vs OLTP, 컬럼 지향 저장, Vectorized Execution
- 시각화: 행 vs 컬럼 저장 비교, MergeTree vs LSM Tree
-
- Column, Block, Parser, Interpreter, Processor
- 시각화: SQL 실행 파이프라인 전 과정
-
3장. Context, Thread Pool, 동시성 제어
- 설정 계층, CPU Slot 기반 동시성
- 4장. Table Parts — 파트의 물리적 구조
- 5장. Table Partitions — 데이터 lifecycle 관리
- 시각화: 잘못된 파티셔닝이 파트 폭증을 일으키는 과정
- 6장. Table Part Merges — 백그라운드 머지
- 시각화: 머지 4단계, FINAL 키워드 성능 저하 원인
- 7장. Primary Index — Sparse Index, ORDER BY 키 설계
- 시각화: ORDER BY 키 순서에 따른 850배 성능 차이
- 8장. Shards와 Replicas — 분산 아키텍처
- 시각화: 분산 쿼리 라우팅, 복제 동작
- 9장. INSERT 전략 선택 — 동기/비동기, 배칭
- 10장. 피해야 할 패턴들 — 안티패턴 모음
- 11장. 모니터링과 트러블슈팅 — 증상별 대응
실제 서비스에서 마주치는 요구사항을 ClickHouse로 어떻게 풀어내는지.
| # | 도메인 | 핵심 개념 |
|---|---|---|
| 01 | 🛒 E-commerce | 복합 엔진 활용, MV 대시보드 |
| 02 | 📊 Observability | Async Insert, Map, Bloom filter |
| 03 | 🌡️ IoT 시계열 | DoubleDelta/Gorilla 코덱, 다단계 집계 |
| 04 | 📈 Product Analytics | HyperLogLog, Funnel, Retention |
| 05 | 💰 광고 이벤트 | Collapsing, 샘플링, 부정 클릭 탐지 |
실수 상황별 증상 → 원인 → 진단 → 해결 과정을 따라가는 케이스 스터디.
| 케이스 | 핵심 증상 |
|---|---|
| A1. 일 단위 파티셔닝 | Too many parts, INSERT 중단 |
| A2. 고카디널리티 파티셔닝 | 파티션 수만 개, 서버 시작 수분 |
| 케이스 | 핵심 증상 |
|---|---|
| B1. ReplacingMergeTree + FINAL 누락 | 중복 행, 집계값 2배 |
| B2. CollapsingMergeTree sign 꼬임 | 잔액/수량 음수 또는 소실 |
| B3. SummingMergeTree String 컬럼 | 머지 후 문자열 값 임의 변경 |
| 케이스 | 핵심 증상 |
|---|---|
| C1. SELECT * 남용 | 쿼리가 예상보다 10~100배 느림 |
| C2. FINAL 남발 | 싱글 스레드 실행, CPU 폭증 |
| C3. Distributed GROUP BY OOM | Memory limit exceeded |
| C4. DISTINCT vs uniq | DAU 쿼리 10초 이상, 메모리 GB |
| 케이스 | 핵심 증상 |
|---|---|
| D1. 건당 INSERT | Too many parts, DB 응답 불가 |
| D2. Distributed 테이블에 INSERT | 쓰기 지연, 이중 네트워크 홉 |
| D3. Mutation 남발 | 백그라운드 머지 중단, 디스크 2배 |
개념을 아는 상태에서 "어떻게 하더라?" 빠르게 찾기 위한 레퍼런스.
| 파일 | 내용 |
|---|---|
| merge_tree_engines.md | 7가지 엔진 비교, 선택 플로우차트 |
| type_selection.md | 타입 선택 가이드, 압축 코덱 |
| insert_strategy_flowchart.md | INSERT 전략 의사결정 트리 |
| troubleshooting_queries.md | 증상별 진단 쿼리 모음 |
| version_history.md | 버전별 주요 변경사항 (23.x ~ 25.x), LTS 선택 가이드 |
ClickHouse를 쓸 때 지켜야 할 원칙을 한 페이지에 압축:
1. OLTP가 필요하면 ClickHouse를 쓰지 말 것
→ 트랜잭션, 단일 행 UPDATE/DELETE가 잦으면 MySQL/PostgreSQL
2. ORDER BY 키는 "쿼리 WHERE 패턴"에 맞춤
→ 저카디널리티 → 고카디널리티 순서
→ 테이블 생성 후 변경 불가, 사전 설계 필수
3. 파티셔닝은 "데이터 관리용"이지 "쿼리 최적화용" 아님
→ TTL, DROP PARTITION에 사용
→ 파티션 수 1,000 이하 유지 (과도하면 파트 폭증)
4. LowCardinality(String)을 기본값으로
→ 수천 고유값 이하면 무조건 적용
5. 타입은 최소한으로
→ 습관적 Int64/Float64 금지
1. 배치 INSERT (최소 1만 행) 또는 Async Insert
→ 건 단위 INSERT = "Too many parts" 즉사
2. Distributed 테이블에 INSERT 금지
→ 로컬 테이블에 직접 INSERT
3. UPDATE/DELETE 대신 INSERT-only 패턴
→ ReplacingMergeTree, CollapsingMergeTree 활용
1. 필요한 컬럼만 SELECT
→ SELECT * 는 컬럼 지향의 장점을 죽임
2. 대시보드는 Materialized View로 사전 집계
→ 원본 스캔 금지
3. FINAL 키워드 최소화
→ argMax, sum(sign) 등으로 대체
4. DISTINCT 대신 uniq (HyperLogLog)
→ 정확도 ~1% 희생, 메모리/속도 수백 배 절감
- 공식 Architecture 문서: clickhouse.com/docs/development/architecture
- Core Concepts: parts, partitions, merges, primary-indexes, shards
- Best Practices: choosing-a-primary-key, avoid-mutations, avoid-optimize-final, selecting-an-insert-strategy
- VLDB 2024 Paper: "ClickHouse - Lightning Fast Analytics for Everyone"
- ClickHouse SQL Playground: sql.clickhouse.com