Spark 3.0.1禁用AQE时count()与show()的Join策略差异疑问
问题分析与解答
核心原因:count()触发的列裁剪与统计重估
Spark处理count()时,会在逻辑层自动做列裁剪——只保留计算count必需的连接键列,生成新的执行计划。这时候Spark会针对裁剪后的计划,重新估算参与Join的数据集大小:
- 原DataFrame的输入文件统计是全表的大小,但裁剪后只剩连接键列,数据量会大幅缩水(远低于10MiB的阈值)。
- 就算禁用了AQE,Spark的Catalyst优化器在逻辑优化阶段,会基于裁剪后的计划重新计算统计信息(比如列的平均长度、总行数估算),不会直接复用原表的文件大小统计。
为什么explain和show()用SortMergeJoin?
df.explain()展示的是原DataFrame的执行计划,没应用count()带来的列裁剪,所以基于全表的文件大小统计,选了SortMergeJoin。df.show()要输出所有列,不会触发列裁剪,执行计划和原计划一致,自然用SortMergeJoin。
关于禁用AQE后的策略选择逻辑
禁用AQE时,Spark确实靠静态统计选Join策略,但这里的静态统计是经过逻辑优化后的计划节点的统计,不是原始输入表的统计。count()的列裁剪属于逻辑优化的一环,Catalyst会给裁剪后的节点算新的统计,判断满足BroadcastHashJoin的阈值条件,最终就选了这个策略。
内容的提问来源于stack exchange,提问作者akhil pathirippilly
相关产品推荐
相关产品推荐

