文章目录
- 一、什么是行式存储和列式存储?
- 二、核心差异一览
- 三、业务案例一:订单详情查询(典型 OLTP)
- 四、业务案例二:销售额统计报表(典型 OLAP)
- 五、真实对比案例(10 亿订单表)
- 六、为什么列式存储在分析场景这么快?
- 七、真实系统中的最佳实践架构
- 八、选型建议
- 九、总结
在数据库选型时,很多性能问题并不是 SQL 写得不好,而是存储模型从一开始就选错了。
本文将通过原理讲解 + 实际业务案例,帮助你真正理解:
为什么有的系统适合行式存储,有的系统必须用列式存储?
一、什么是行式存储和列式存储?
1️⃣ 行式存储(Row-based Storage)
以“行”为单位存储数据,一行的所有字段在物理上连续存放。
示例表:
| order_id | user_id | amount | status |
|---|---|---|---|
| 1 | 1001 | 99.9 | PAID |
| 2 | 1002 | 199.0 | PAID |
行式存储逻辑结构:
[1, 1001, 99.9, PAID] [2, 1002, 199.0, PAID]2️⃣ 列式存储(Column-based Storage)
以“列”为单位存储数据,同一列的数据连续存放。
order_id: [1, 2] user_id: [1001, 1002] amount: [99.9, 199.0] status: [PAID, PAID]二、核心差异一览
| 对比维度 | 行式存储 | 列式存储 |
|---|---|---|
| 存储单位 | 行 | 列 |
| 查询方式 | 点查 | 扫描 |
| I/O | 读整行 | 只读列 |
| 更新 | 快 | 慢 |
| 压缩 | 一般 | 极强 |
| 适合场景 | OLTP | OLAP |
三、业务案例一:订单详情查询(典型 OLTP)
业务需求
用户在 App 中查看自己的订单详情
SELECT*FROMordersWHEREorder_id=123456;数据特点
- 查询单行
- 高频访问
- 需要事务保证
行式存储表现(MySQL)
- 通过B+Tree 索引
- 一次磁盘 I/O 读取整行
- 返回完整记录
👉性能极高,毫秒级返回
列式存储表现(ClickHouse)
- 需要从多个列文件中拼装一行
- 不适合点查
- 并发能力弱
❌明显不适合
结论
订单系统、用户系统必须使用行式存储
四、业务案例二:销售额统计报表(典型 OLAP)
业务需求
统计 2025 年每个月的销售额
SELECTtoMonth(create_time)ASmonth,SUM(amount)AStotal_amountFROMordersWHEREcreate_time>='2025-01-01'GROUPBYmonth;行式存储的执行方式(MySQL)
- 扫描整张 orders 表
- 每一行都读取所有字段
- 大量无效 I/O
📉数据量一大,查询变慢
列式存储的执行方式(ClickHouse)
- 只读取
create_time、amount两列 - 列数据连续、压缩率高
- 向量化并行计算
📈百万级数据,秒级返回
结论
统计分析场景,列式存储碾压行式存储
五、真实对比案例(10 亿订单表)
表规模
- 订单表:10 亿行
- 字段数:20
- 查询字段:2 个
性能对比
| 存储方式 | 扫描数据量 | 查询耗时 |
|---|---|---|
| 行式存储 | 全行 20 列 | 60+ 秒 |
| 列式存储 | 仅 2 列 | 2~3 秒 |
👉差距来源:I/O + 压缩 + 并行
六、为什么列式存储在分析场景这么快?
1️⃣ 只读取必要的列
- 减少磁盘 I/O
2️⃣ 高效压缩
- 同类型数据连续
- 压缩比 5~10 倍
3️⃣ 向量化执行
- 一次处理 1024 行
- CPU Cache 友好
七、真实系统中的最佳实践架构
行式 + 列式 混合使用(最常见)
业务系统 | MySQL(行式存储,OLTP) | CDC / MQ | ClickHouse(列式存储,OLAP)- MySQL:写、事务、点查
- ClickHouse:报表、分析、统计
👉各司其职,性能最大化
八、选型建议
快速判断口诀
写多用行式,算多用列式
| 场景 | 建议 |
|---|---|
| 订单 / 用户 | 行式存储 |
| BI 报表 | 列式存储 |
| 实时分析 | 行式 + 列式 |
| 数据仓库 | 列式存储 |
九、总结
- 行式存储是事务系统的基石
- 列式存储是分析系统的利器
- 二者不是替代关系,而是协作关系
一个成熟的系统,一定同时使用行式存储和列式存储