Spark SQL谓词下推与列式存储
请解释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(分析查询) |
两者协同工作:
- 列裁剪 + 谓词下推: 只读取需要的列(投影)+ 只读取符合条件的行(过滤)
- 将谓词下推到Parquet的**行组(Row Group)**的统计信息(min/max)级别
- Parquet利用**元数据(统计信息)**跳过不包含匹配数据的行组(谓词下推 + 聚簇索引效果)
- ORC更进一步支持Bloom Filter和轻量级索引
效果: 可减少90%以上的I/O,是数仓查询的关键优化手段。