Parquet 与 CSV:体积、扫描量与费用

「换成 Parquet 能省多少」这个问题,存储只是小头。改一改下面的表形状和查询形状, 看压缩、列裁剪、分区裁剪各自贡献了几倍,以及按 $5/TB 一个月要花多少。

表的形状
典型查询
CSV 扫描
Parquet 扫描
单次查询费用
月度查询费用

Athena 每次查询最少按 10 MB 计费,小表上这一条会主导账单。

存储
CSV(未压缩) 1.0x
CSV + gzip
Parquet

Parquet 省下

省下的钱来自哪里

  • 压缩
  • 列裁剪
  • 分区裁剪

计算全部在浏览器里完成。

三种节省不是加起来,而是乘起来

压缩只是一个固定系数:同一张表,Parquet 大概是未压缩 CSV 的 1/4 到 1/8,取决于列的基数 —— 这里让你选「数据特征」而不是只选编码,原因就在这: 字典编码和 RLE 面对一个只有六种取值的 status 列几乎能压到不要钱,面对一列 UUID 则基本无能为力。 编码(Snappy / ZSTD / GZIP)只是在这个基础上再调 20% 上下。

真正拉开差距的是另外两项,而且它们相乘: 40 列里只查 4 列,列式存储只读那 4 列的数据块 —— 这是 10 倍; 分区裁剪把要读的分区从全表压到 10% —— 这又是 10 倍。 CSV 拿不到第一项(行式文件必须整行读出来才能取一个字段),所以差距会落在两个数量级上, 而不是压缩带来的那 4 到 8 倍。

有两条边界要记住。一是 Athena 每次查询至少按 10 MB 计费, 小表上你优化到 200 KB 也还是按 10 MB 收 —— 上面的计算已经把这个下限算进去了, 你把行数调小就能看到两边的费用贴到同一个值。 二是这里没有算 row group 级别的统计信息裁剪(min/max 谓词下推):真实的 Parquet 查询 往往还能再少读一截,所以 Parquet 一侧是偏保守的估计。

没有计入的还有:小文件问题(几百万个 1 MB 的文件会让元数据开销和请求数主导成本)、 以及 Parquet 写入侧更高的 CPU 开销。

延伸阅读