Spark读取Hive表时是否会将整张表全部加载到内存?
Apache Spark 内存加载行为问题解答
参考Hive表样例数据
| Name | Age | Marks |
|---|---|---|
| A | 50 | 100 |
| B | 50 | 100 |
| C | 75 | 200 |
以下结论默认基于Spark开启Catalyst优化、Hive表使用Parquet/ORC等支持谓词下推、列裁剪的列存储格式的场景,若使用无优化的纯文本存储或手动关闭了下推相关配置,行为会有差异。
四个代码片段的具体执行表现
- 代码1:
spark_session.sql("SELECT name, age from table").collect()- 加载到内存的内容:仅
name、age两列的全部3行数据,Marks列不会被读取 - 过滤执行时机:列裁剪逻辑直接下推到数据源,不会先加载全表3列到内存再删除
Marks列
- 加载到内存的内容:仅
- 代码2:
spark_session.sql("SELECT * from table WHERE age=50").collect()- 加载到内存的内容:仅
age=50的2行(A、B对应行)的全部3列数据 - 过滤执行时机:行过滤条件
age=50下推到数据源,仅读取符合条件的行,不会先加载全表3行到内存再过滤
- 加载到内存的内容:仅
- 代码3:
spark_session.sql("SELECT * from table").select("name", "age").collect()- 加载到内存的内容:和代码1完全一致,仅
name、age两列的全部3行数据 - 过滤执行时机:Catalyst优化器会将
select的列裁剪逻辑和前面的查询语句合并下推到数据源,不会先加载全表3列再做列筛选
- 加载到内存的内容:和代码1完全一致,仅
- 代码4:
spark_session.sql("SELECT * from table").filter(df.age == 50).collect()- 加载到内存的内容:和代码2完全一致,仅
age=50的2行(A、B对应行)的全部3列数据 - 过滤执行时机:优化器会将
filter的行过滤条件下推到数据源,不会先加载全表3行再做行筛选
- 加载到内存的内容:和代码2完全一致,仅
内容的提问来源于stack exchange,提问作者Zeeshan Shamsuddeen
相关产品推荐
相关产品推荐

