阶段一 · 概念入门

什么是 ClickHouse:OLAP 与列式存储

一句话总结

ClickHouse 是一款列式存储OLAP 数据库,专为海量数据的快速分析查询而设计.
如果 MySQL 查询跑了几秒甚至几十秒还没出结果,那可能就是 ClickHouse 该上场的时候了.

从一个场景出发

假设在做一个电商后台,运营同事提了一个需求:"我想看过去一年,每个省份每天的订单量和销售额,能按日期和地区自由筛选."

用 MySQL 写一条查询:

SELECT province, DATE(created_at) AS day,
COUNT(*) AS order_cnt, SUM(amount) AS total
FROM orders
WHERE created_at >= '2025-01-01'
GROUP BY province, day
ORDER BY day, province;

一年几百万订单,这条查询跑了 8 秒.运营说"还行,但我还想加上用户留存,复购率,SKU 维度...",每条新需求都在挑战查询时间的上限.

这不是 MySQL 的问题--是工具和场景不匹配. 这条查询属于"分析型查询",而 MySQL 是为"事务型操作"设计的. 这时候需要一个专门干这件事的数据库--ClickHouse.

数据库的两类工作负载

数据库领域有一个经典划分:OLTPOLAP. 这两个词决定了数据库的架构设计走向,理解它们是理解 ClickHouse 的前提.

OLTP(Online Transaction Processing) OLAP(Online Analytical Processing)
干什么 处理业务交易--下单,扣库存,改密码 分析海量数据--报表,看板,用户画像
典型操作 少量行的增删改查,按主键定位 大量行的聚合扫描,跨多列过滤
查询特点 点查:WHERE id = 12345 范围扫:WHERE date BETWEEN ... GROUP BY ...
数据量级 每次操作几行,但并发很高 单次查询可能扫描数十亿行
核心指标 延迟(Latency):毫秒级响应 吞吐(Throughput):每秒处理多少数据
代表产品 MySQL,PostgreSQL,Oracle ClickHouse,Doris,Snowflake,Hive
数据写入 逐行实时写入,支持更新删除 批量追加写入,更新/删除代价高

OLTP = 收银台 -- 关心"这笔订单多少钱,库存够不够",动作快,一件一件来.
OLAP = 年度财报 -- 关心"哪个品类增长最快,哪个月利润率最高",要把全年数据汇总起来看.
同一个公司的数据,两种完全不同的使用方式.

现在问题来了:OLTP 和 OLAP 对数据库的读写模式差异如此之大,用同一套存储结构能同时做好两件事吗? 答案是不能.这就引出了行存与列存的分野.

行存与列存:核心分水岭

假设有一张用户表,存了 4 列数据:

id name age city
1 张三 28 北京
2 李四 35 上海
3 王五 22 北京
4 赵六 41 深圳

行式存储(Row Store)

MySQL,PostgreSQL 等 OLTP 数据库把一行数据完整地存在一起:

磁盘布局: [1,张三,28,北京] [2,李四,35,上海] [3,王五,22,北京] [4,赵六,41,深圳]
← 第 1 行 → ← 第 2 行 → ← 第 3 行 → ← 第 4 行 →

好处:读一行时,一次磁盘 I/O 就能拿到整行所有列--OLTP 的"按主键查一行"刚好需要这个.

坏处:如果只想算 AVG(age),也得把所有行的 name,city 一起读进内存--这些查询并不需要的列占了带宽和内存,纯属浪费.

列式存储(Column Store)

ClickHouse 反其道而行,把同一列的所有值存在一起:

磁盘布局: [1,2,3,4] [张三,李四,王五,赵六] [28,35,22,41] [北京,上海,北京,深圳]
← id → ← name → ← age → ← city →

好处:SELECT AVG(age) FROM users 只读 age 那一列的数据,其余列完全跳过. 列中同类型数据压缩率极高(比如 age 全是整数,用 Delta 编码可以把 [28,35,22,41] 压成几个字节).

坏处:如果要取一整行的所有列,得从四个不同的列文件中分别定位和拼接--OLTP 的点查场景下这是灾难.但 OLAP 很少取整行,通常只关注某几列的聚合.

行存 = 一本按章节排列的书 -- 读小说时从第一页翻到最后一页,每次读一整页.
列存 = 一套按科目分册的习题集 -- 做"全书动词出现频率统计"时,只翻"词性"那一册,跳过名词/形容词,直奔动词,工作量骤减.

行存和列存不是谁替代谁的关系,它们各自适合不同类型的工作负载. 下面的对比帮助建立直觉:

维度 行式存储 列式存储
典型产品 MySQL, PostgreSQL ClickHouse, Parquet 格式
适合查询 SELECT * WHERE id = 1 SELECT city, AVG(age) GROUP BY city
单行读取 极快(一次 I/O) 慢(需跨多列拼接)
按列聚合 慢(读入无关列) 极快(只读相关列)
压缩效率 一般(行内数据类型混杂) 极高(同列数据类型一致)
写入模式 原地更新(UPDATE) 追加写入(INSERT),更新需重建

ClickHouse 是什么

有了 OLAP 和列存的背景,ClickHouse 的定义就很好理解了:

ClickHouse(简称 CH)是俄罗斯搜索引擎 Yandex 于 2016 年开源的列式 OLAP 数据库管理系统(Column-Oriented OLAP DBMS),使用 C++ 编写,专为海量数据的实时分析查询而设计.

拆开来看,ClickHouse 的核心设计选择都围绕一个目标:用最短的时间扫描最多的数据.

它是怎么做到快的?

ClickHouse 的快不是某一个技巧,而是一组策略的叠加.这里先建立整体印象,不用逐条死记--后续各篇会逐个展开:

策略 解决了什么问题 关键数字
列式存储 查询只读需要的列,减少 I/O 无关列完全不读
数据压缩 同列数据相似度高,压缩比惊人 通常 5~10 倍压缩
向量化执行 一次 CPU 指令处理一批数据,而非逐行 SIMD 批处理数千行
稀疏索引 不建 B-Tree 全索引,每隔一段距离放一个标记 索引体积仅为数据的 ~1%
分区裁剪 按时间等维度分区,无关分区直接跳过 分区级粒度跳过
多核并行 单个查询自动拆成多线程执行 充分利用 CPU 多核
分布式 多台机器分摊计算和存储 线性扩展

直觉先行

不用被"向量化""稀疏索引"这些词吓到. 本质逻辑很简单:列存减少读取量,压缩让数据变小,向量化让 CPU 处理更高效,分区和索引直接跳过不相关数据.

层层叠加,最终的效果是--本来要扫 10GB 的查询,实际可能只读了 50MB.

一个直观的对比

Yandex 在公开 Benchmark 中展示过这样的数据(同一台机器,1 亿行数据集):

查询类型 MySQL (InnoDB) ClickHouse 倍数
简单 COUNT ~4 秒 ~0.03 秒 ~130x
GROUP BY 聚合 ~15 秒 ~0.1 秒 ~150x
多维度过滤 + 排序 超时 / 极慢 ~0.5 秒 数十倍到数百倍

这不是魔法,就是架构选择带来的差距--专为此类查询设计的存储结构和执行引擎,比通用引擎高效几个数量级.

ClickHouse 不擅长什么

了解一个工具的边界,比了解它的能力更重要.以下场景不适合用 ClickHouse,或者需要额外的设计来规避:

场景 为什么不合适 替代方案 / 变通
频繁的单行 UPDATE / DELETE CH 的更新是异步 Mutation,代价高,不可预测 用 MySQL 处理 OLTP 业务,CH 只做分析层
高并发点查(数千 QPS 按 ID 取一行) CH 为吞吐优化,单次查询延迟不如 KV 存储 Redis / MySQL 做主键查询,CH 做聚合分析
实时逐行写入 + 立刻查询 CH 的写入是按批次最优的,频繁小批量写入效率低 应用层攒批(如每秒一批)再写入
需要事务(ACID) CH 不支持跨行,跨表的事务 事务场景留在 MySQL / PostgreSQL
需要复杂 JOIN CH 的 JOIN 设计为右表小表广播,大表 JOIN 性能不佳 宽表建模,物化视图预计算

常见误区

新人最容易犯的错误是把 ClickHouse 当成 MySQL 的替代品. 它不是. ClickHouse 和 MySQL 是协作关系,不是替代关系.

业务数据仍然存在 MySQL 里处理交易,然后同步(或直接双写)到 ClickHouse 里做分析. 这叫OLTP + OLAP 分离架构.

与常见数据库的关系

把 ClickHouse 放进你已有的技术栈认知里,梳理与其他数据库的关系:

数据库 类型 与 ClickHouse 的关系
MySQL / PostgreSQL OLTP 行存 互补. MySQL 管交易,CH 管分析. 数据从 MySQL 同步到 CH.
Redis 内存 KV / 缓存 各管各的. Redis 管热数据和缓存,CH 管海量历史数据分析.
Elasticsearch 搜索引擎(倒排索引) 部分重叠. ES 擅长全文搜索和日志检索,CH 擅长聚合分析. 实践中常组合使用:ES 做日志检索,CH 做指标聚合.
Kafka 消息队列 / 流平台 上下游. Kafka 作为数据管道,实时数据经 Kafka 流入 CH. CH 也内置了 Kafka 表引擎直接消费.
Hive / Spark 大数据批处理 替代/补充. CH 在实时交互式分析场景下比 Hive/Spark 快得多,但 Spark 的批处理生态更成熟.

本篇要点

  • OLTP vs OLAP: OLTP 处理交易(点查,小事务),OLAP 处理分析(大范围扫描,聚合). 两种截然不同的工作负载.
  • 行存 vs 列存: 行存适合"取一整行",列存适合"只读几列做聚合". 列存通过跳过无关列和高效压缩大幅降低 I/O.
  • ClickHouse 是列式 OLAP 数据库: 通过列存 + 压缩 + 向量化 + 稀疏索引 + 分区 + 并行等多层策略叠加,实现海量数据的秒级分析.
  • ClickHouse 不是 MySQL 替代品: 不擅长 UPDATE/DELETE,高并发点查,事务. 正确做法是 OLTP + OLAP 分离架构,各司其职.
  • 技术栈定位: ClickHouse 与 MySQL,Redis,Kafka 等是协作关系,各管各自擅长的领域.

下一站

理解了"是什么"和"为什么"之后,下一篇 02 - 快速上手:安装部署与第一个查询 用 Docker 在本地启动 ClickHouse,跑通第一条查询. 概念落地,动手为先.