题目重点:针对双方都大的 Join,先核键与基数,再看 AQE、shuffle、倾斜和可复用物理布局。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版以两张均无法整体广播的大表按等值键 inner join 为例;若其中一边过滤后足够小,广播可能是另一方案。
- 精确结果需保留重复键的多对多行数,不能为了性能无条件去重或仅保留任意一行。
解题路线
- 先确认 join 类型、键唯一性、NULL 语义、过滤条件和预期输出基数;执行 `explain` 并查看输入统计与实际 task 分布,判断瓶颈是扫描、shuffle 还是输出爆炸。
- 在 join 前过滤/列裁剪,能按业务等价规则预聚合的一边先缩小;但只有聚合结果能替代原明细时才做,不能改变多对多语义。
- 双方仍很大时通常需要按 join key 的 shuffle 计划;配置合适并行度与文件布局,使用可靠表统计。若两表已按兼容分区/桶布局存储,可评估减少重复 shuffle 的可行性。
- 热点键会使单分区超大:先分辨是正常高基数输出还是不均匀 shuffle;对可拆热点键做定向 salting、分离处理,或让 AQE skew join 优化。广播提示仅在过滤后小表足够小且节点内存可承受时使用。
- 测 shuffle bytes、最慢 task、输出行数和正确性对账;join hint 是建议,实际策略受 join 类型与优化器限制,不能只凭 hint 推断计划。
手动走一遍
A、B 都各有大量数据,键 X 在 A 有 10 万行、B 有 10 万行,则该键的 inner join 可能产生 100 亿行;这时单纯 salting 不能消除结果规模。若 B 实际先按条件过滤到很小,则可重新评估广播。数字只是数量级示例。
规模与取舍
等值 join 的网络 shuffle 通常与两侧参与记录规模相关,输出行数可能达同键频数乘积之和;最坏多对多输出可远大于输入。内存、磁盘与时延需按键分布和实际执行计划核算。
易错点与追问
容易失分的边界
- 两张表都大却无依据强制 broadcast,一侧复制到所有 executor 触发 OOM。
- 忘记重复键,误判结果规模。
- 盲目 salting 但不复制匹配侧/不合并结果,漏行或重复。
- 把 AQE 当万能修复,不看实际版本与开启状态。
- 为提高速度随意去重,改变业务语义。
继续深挖
- 一边过滤后 5MB,策略会怎样变?
- 热点键代表真实多对多输出爆炸时怎样从产品需求降低结果?
- 如何确认 AQE 实际改用了 skew join 优化?
- left outer join 对广播方向和 NULL 有何约束?
技术参考
- Apache Spark SQL Performance Tuning:统计、广播、AQE 与 skew join 调优依据。
- Apache Spark Join Hints:hint 是策略建议且受 join 类型限制。
