Parquet 和 ORC 到底有啥区别?别再云里雾里了,咱今天把列式存储聊明白!
大家好,我是你们熟悉的 Echo_Wish。
最近后台私信问我:“师傅,Parquet 和 ORC 到底该怎么选?看网上资料越看越迷糊,感觉它俩就是双胞胎。”
我说一句大实话:
Parquet 和 ORC 是双胞胎没错,但一个偏文科,一个偏理科,理念不同、能力不同、适用场景也不同。
今天,咱就从工程师视角把 列式存储的核心逻辑 + Parquet/ORC 内部机制 + 选型建议 讲得明明白白。
保证你看完之后,能在开技术会时拍着桌子说:
“这个任务我们必须选 ORC!” 或 “这个场景不用犹豫,直接 Parquet!”
开整!
🌟 一、为什么要列式存储?别只背概念
咱先别急着上标准答案“为分析优化、压缩率高、IO 少”这种 PPT 话。
我用一句人话解释:
行式存储=仓库把货按订单放,列式存储=仓库把货按“属性”分区放。
如果你常干 OLAP 分析,那你 90% 的时间在做:
- 统计某列
- 过滤某列
- 分组某列
- 求和某列
这种情况下,扫描全行是非常浪费的,特别是字段很多的时候 —— 行式存储就像 Excel 每次都要把整行翻出来,速度自然慢。
列式存储把字段拆开存储,扫描少、压缩高,分析快,天生适合大数据。
这就是为什么 Hive、Presto、Trino、Spark SQL、Iceberg、Hudi 都离不开它。
🌟 二、Parquet 与 ORC:它俩是在“同一个目标,不同的哲学”
你可以这么理解:
- Parquet:跨生态、跨引擎的通用格式,偏向 Spark/Presto 等多引擎混用的体系。
- ORC:Hadoop 家族亲儿子,为 Hive 做了非常多的专门优化。
下面我拆开它俩的内部机制讲。
🔍 三、Parquet 内部结构:字段式的精致主义者
Parquet 的结构非常“分层、规整、易扩展”。
大概长这样:
File
├─ Row Groups
│ ├─ Column Chunk A
│ │ ├─ Pages
│ ├─ Column Chunk B
│ │ ├─ Pages
...
└─ Footer (Schema + Metadata)
💡 关键点:
1)以 Row Group 为单位组织数据
- 一个 Row Group 通常 128MB ~ 1GB
- 大数据引擎读取时可以并发处理多个 Row Group
2)每列的数据独立压缩
每列可以不同编码,例如:
- 字符串:DICT
- int:RLE
- 布尔:bit-packed
非常适合 高基数+稀疏 的列。
3)Parquet 注重跨系统兼容性
Spark、Presto、Impala、ClickHouse、Iceberg 都用它。
📌 代码示例(PySpark 写入 Parquet)
df.write.mode("overwrite").parquet("/tmp/parquet_demo")
🔍 四、ORC 内部结构:为 Hive 而生的“压缩狂魔”
ORC 的结构看起来比 Parquet 更“工程化”:
File
├─ Stripes (大块数据)
│ ├─ Index Data
│ ├─ Row Data
│ └─ Stripe Footer
└─ File Footer
💡 关键点:
1)以 Stripe(Stripe ≈ 64MB 默认) 为核心
一个 Stripe 包含:
- Row Data(核心数据)
- Index Data(索引)
- Stripe Footer(压缩、偏移信息)
内置的 Stripe Index 能让 ORC 的谓词下推更狠。
2)压缩能力更强
ORC 默认对字符串和整数使用更 aggressive 的字典编码 + RLE2,压缩率往往比 Parquet 高 10%-30%。
3)统计信息非常丰富(Hive 优化器最爱)
例如:
- min/max
- distinct count
- bloom filter
- null count
- column statistics
Hive 的 CBO(成本优化器)依赖这些统计信息做优化。
📌 代码示例(Spark 写 ORC)
df.write.mode("overwrite").orc("/tmp/orc_demo")
⚔️ 五、核心差异总结(最干的部分)
| 维度 | Parquet | ORC |
|---|---|---|
| 发源地 | Twitter + Cloudera | Hortonworks(Hive 原生) |
| 最佳搭档 | Spark / Presto / Iceberg | Hive / ETL 批处理 |
| 压缩率 | 高 | 更高(通常) |
| 统计信息 | 足够 | 特别丰富 |
| 查询加速 | 优秀 | 极优秀 |
| 小文件处理 | 较好 | 略优 |
| 写入速度 | 稍快 | 略慢 |
| 跨生态兼容性 | 最佳 | 一般 |
写成一句话:
你要生态?选 Parquet。
你要极致压缩+极致 Hive 查询?选 ORC。
💼 六、实际工程选型建议(我最让人点赞的部分)
✔ ① Spark 生态+多系统混用
Parquet 是王道。
你很可能还有 Presto/Trino、ClickHouse、Iceberg/Hudi/Lakehouse,要兼容就选它。
✔ ② 基于 Hive 的离线数仓 + 大批量 ETL
ORC 更稳。
Hive 的优化和 ORC 一家亲,性能差异能达到 20%-50%。
✔ ③ 强压缩率需求(数据湖冷存储)
ORC 是更实惠的选择。
✔ ④ 流式写入 + 下游多引擎消费
Parquet 更均衡。
✔ ⑤ Iceberg/Hudi/Delta Lake
绝大多数推荐默认:Parquet
(数据湖标配,不解释。)
🧪 七、一个真实案例:同样 100GB 文本表 Parquet vs ORC
我们当时做了一个测试(Spark + Hive 混合场景):
- 数据量:100GB 原始 JSON
- 字段数:64 列
- 业务场景:Ad-hoc 分析 + 部分 Hive Join
📊 结果非常典型:
| 指标 | Parquet | ORC |
|---|---|---|
| 压缩后体积 | 16.3 GB | 11.9 GB |
| Hive 查询性能 | 1.0x | 1.3~1.5x |
| Spark 查询性能 | 1.0x | 0.95x |
| 兼容性 | ⭕ perfect | ❌ 稍弱 |
看结果就一句话:
- ORC = Hive 场景“专用武器”
- Parquet = 通用型“万能螺丝刀”
🔚 八、写在最后:格式选对,你的数仓就少走一半弯路
很多团队之所以数仓慢、查询卡、资源浪费,其实根本不是 Spark/Hive 的问题,而是——
底层文件格式选错了,天生短板再怎么调参也补不回来。
我自己的经验是:
- 大数据生态越来越多引擎协作 → Parquet 适应性最强
- Hive 仍然是很多公司的离线基础设施 → ORC 在这块依旧无敌
- 数据湖时代已经到了 → Parquet 是事实标准