一句话总结
ClickHouse 是一款列式存储的OLAP 数据库,专为海量数据的快速分析查询而设计.
如果 MySQL 查询跑了几秒甚至几十秒还没出结果,那可能就是 ClickHouse 该上场的时候了.
从一个场景出发
假设在做一个电商后台,运营同事提了一个需求:"我想看过去一年,每个省份每天的订单量和销售额,能按日期和地区自由筛选."
用 MySQL 写一条查询:
|
一年几百万订单,这条查询跑了 8 秒.运营说"还行,但我还想加上用户留存,复购率,SKU 维度...",每条新需求都在挑战查询时间的上限.
这不是 MySQL 的问题--是工具和场景不匹配. 这条查询属于"分析型查询",而 MySQL 是为"事务型操作"设计的. 这时候需要一个专门干这件事的数据库--ClickHouse.
数据库的两类工作负载
数据库领域有一个经典划分:OLTP 和 OLAP. 这两个词决定了数据库的架构设计走向,理解它们是理解 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 数据库把一行数据完整地存在一起:
|
好处:读一行时,一次磁盘 I/O 就能拿到整行所有列--OLTP 的"按主键查一行"刚好需要这个.
坏处:如果只想算 AVG(age),也得把所有行的 name,city 一起读进内存--这些查询并不需要的列占了带宽和内存,纯属浪费.
列式存储(Column Store)
ClickHouse 反其道而行,把同一列的所有值存在一起:
|
好处: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,跑通第一条查询. 概念落地,动手为先.