Parquet与Arrow:不同的层 | AI生成和翻译

Home 2026.06

问题: 在 Parquet 和 Arrow 之间,哪个性能更好?

回答:

它们并非真正的竞争者——在数据栈的不同层级解决不同的问题。但我们可以精确地比较它们。

它们是什么

  Parquet Arrow
类型 列式存储格式(磁盘上) 列式内存格式(内存中)
设计目标 长期存储、压缩、查询下推 零拷贝 IPC、进程内分析、SIMD
行组/批次 行组(MB 级数据块) RecordBatches(可配置)
编码方式 RLE、字典、增量、位打包 + Snappy/Zstd/LZ4 原始类型缓冲区(默认无压缩)
标准归属 Apache(源于 Twitter/Cloudera) Apache(源于 Wes McKinney / Cloudera)

性能分解

磁盘 I/O → Parquet 获胜

Parquet 的压缩与编码意味着文件大小比原始 Arrow IPC 文件小 5–10 倍。对于从 S3/NFS 的冷读取,Parquet 凭借谓词下推和列剪枝大幅胜出——你在文件格式层面就跳过了数据读取。

# Parquet 只读取你请求的列——在 C++ 读取器层面实现
import pyarrow.parquet as pq
table = pq.read_table("data.parquet", columns=["user_id", "event"])

内存计算 → Arrow 获胜(差距悬殊)

Arrow 缓冲区具有 SIMD 友好、缓存对齐、进程/语言间零拷贝的特点。无需反序列化。

import pyarrow as pa
import pyarrow.compute as pc

# SIMD 向量化,无 Python 循环开销
result = pc.sum(table.column("revenue"))

Parquet 数据在进行计算前必须先解码为 Arrow——这正是 DuckDB、Polars 和 pandas 2.0 内部所做的。

序列化 / IPC → Arrow 获胜

Arrow IPC(Feather v2)本质上是零拷贝的。读取和写回一个 1GB 数据集:

Parquet 写入:~2–5 秒(压缩开销)
Arrow IPC 写入:~0.1–0.3 秒(memcpy 速度)

Parquet 读取:~0.5–1 秒(解压 + 解码)
Arrow IPC 读取:~0.05 秒(mmap,近乎零)

查询引擎同时使用两者

真正的模式是磁盘上的 Parquet → 内存中的 Arrow

S3/磁盘          ──[Parquet]──►  DuckDB/Polars  ──[Arrow]──►  结果
(压缩、                        (解码为
 列剪枝、                        Arrow 缓冲区,
 谓词下推)                       运行 SIMD 操作)

DuckDB、Polars、DataFusion、Spark 和 BigQuery 都在内部执行此操作。

具体数据(粗略,依赖硬件)

操作 Parquet Arrow IPC
从磁盘读取 1GB ~0.5–2 秒 ~0.05–0.1 秒(mmap)
写入 1GB ~2–5 秒 ~0.1–0.3 秒
文件大小(原始 1GB) ~100–300MB ~900MB–1GB
列扫描(内存中) 不适用(已解码) ~1–5 GB/s SIMD

何时使用哪个

使用 Parquet 的场景:

使用 Arrow(IPC/Feather)的场景:

实际示例——你的 CLI 代理工作流

如果你的 ww/zz 代理处理大型数据集:

import pyarrow as pa
import pyarrow.ipc as ipc
import pyarrow.parquet as pq

# 从冷存储加载(Parquet,压缩)
table = pq.read_table("events.parquet", columns=["ts", "event", "user_id"])

# 将热工作集缓存为 Arrow IPC,以便快速重读
with ipc.new_file("events_cache.arrow", table.schema) as writer:
    writer.write_table(table)

# 下次运行——亚 100 毫秒重新加载
with ipc.open_file("events_cache.arrow") as reader:
    table = reader.read_all()

总结


Back Donate