在数据库选型时,很多性能问题并不是 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 * FROM orders WHERE order_id = 123456;

数据特点

  • 查询单行
  • 高频访问
  • 需要事务保证

行式存储表现(MySQL)

  • 通过 B+Tree 索引
  • 一次磁盘 I/O 读取整行
  • 返回完整记录

👉 性能极高,毫秒级返回


列式存储表现(ClickHouse)

  • 需要从多个列文件中拼装一行
  • 不适合点查
  • 并发能力弱

明显不适合


结论

订单系统、用户系统必须使用行式存储


四、业务案例二:销售额统计报表(典型 OLAP)

业务需求

统计 2025 年每个月的销售额

SELECT
  toMonth(create_time) AS month,
  SUM(amount) AS total_amount
FROM orders
WHERE create_time >= '2025-01-01'
GROUP BY month;

行式存储的执行方式(MySQL)

  • 扫描整张 orders 表
  • 每一行都读取所有字段
  • 大量无效 I/O

📉 数据量一大,查询变慢


列式存储的执行方式(ClickHouse)

  • 只读取 create_timeamount 两列
  • 列数据连续、压缩率高
  • 向量化并行计算

📈 百万级数据,秒级返回


结论

统计分析场景,列式存储碾压行式存储


五、真实对比案例(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 报表 列式存储
实时分析 行式 + 列式
数据仓库 列式存储

九、总结

  • 行式存储是 事务系统的基石
  • 列式存储是 分析系统的利器
  • 二者不是替代关系,而是 协作关系

一个成熟的系统,一定同时使用行式存储和列式存储

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐