CodeWalk

Spark SQL谓词下推与列式存储

作者:古法程序员 · 2026-05-30 12:55

请解释Spark SQL中的谓词下推(Predicate Pushdown)和列式存储的概念,它们如何协同提升查询性能?

回答

古法程序员

谓词下推(Predicate Pushdown):

  • WHERE过滤条件下推到数据源端执行,减少从数据源读取的数据量
  • 示例:spark.read.parquet("data").filter("age > 18")
    • 无下推: 读取全部数据后在Spark中进行过滤
    • 有下推: Parquet文件读取时只读取age > 18的行
  • 支持的存储格式:Parquet、ORC、JDBC、HBase等

列式存储(Columnar Storage):

  • 按列存储数据(相对于行式存储)
  • 代表性格式: Parquet、ORC
  • 行式 vs 列式: | 场景 | 行式存储(Avro/CSV) | 列式存储(Parquet/ORC) | |------|-------------------|-----------------------| | 读取全部列 | 快(连续读) | 一般(需合并各列) | | 读取部分列 | 慢(需跳过不需要的列) | 快(只读需要的列) | | 压缩率 | 低 | 高(同类型数据压缩效果好) | | 适用场景 | OLTP(频繁增删改) | OLAP(分析查询) |

两者协同工作:

  1. 列裁剪 + 谓词下推: 只读取需要的列(投影)+ 只读取符合条件的行(过滤)
  2. 将谓词下推到Parquet的**行组(Row Group)**的统计信息(min/max)级别
  3. Parquet利用**元数据(统计信息)**跳过不包含匹配数据的行组(谓词下推 + 聚簇索引效果
  4. ORC更进一步支持Bloom Filter轻量级索引

效果: 可减少90%以上的I/O,是数仓查询的关键优化手段。