Spark SQL五大关联策略
内容提要
选择连接策略的核心原则是避免shuffle和sort操作,首选的连接策略是hash连接。连接策略可通过连接提示进行控制,重要因素是连接数据集的大小。广播散列连接和洗牌散列连接是常用的连接策略。洗牌排列合并连接将两张大表按照join key分区洗牌并排序。笛卡尔积连接将两张大表进行分片,再进行笛卡尔积组装子分片。广播嵌套循环连接通过广播小表数据到每个Executor端,并使用内、外两个嵌套的for循环进行关联。
延伸解读
连接策略选择的核心逻辑
文章强调选择连接策略的核心原则是尽量避免shuffle和sort操作,因为这两类操作资源开销大且耗时。因此,不需要shuffle和sort的hash连接策略成为首选。而决定能否采用hash连接的关键因素是连接数据集的大小,这直接影响是否可以选择广播散列连接或洗牌散列连接。理解这一逻辑有助于在实际调优中优先评估数据集规模,而非盲目使用提示。
等值与非等值连接的支持差异
文章指出,等值连接仅包含“=”比较,所有连接策略都支持;而非等值连接包含“<、>、>=、<=”等范围比较,由于需要对不确定值进行嵌套循环,只有笛卡尔积连接(CPJ)和广播嵌套循环连接(BNLJ)支持。这一限制意味着开发者在编写非等值连接条件时,需意识到可选的策略非常有限,不能依赖hash连接或排序合并连接。
连接提示的有限控制能力
Spark SQL提供四种连接提示:BROADCAST、SHUFFLE_MERGE、SHUFFLE_HASH、SHUFFLE_REPLICATE_NL,允许开发者对策略选择进行一定控制。但文章也暗示,提示并非万能,最终策略仍受数据集大小等条件制约。例如广播散列连接有表大小和行数阈值限制,洗牌散列连接还要求较小表至少比大表小3倍以上。因此,提示应结合数据实际情况使用。
各策略的限制条件需提前核查
文章详细列出了每种策略的限制:广播散列连接要求小表小于autoBroadcaseJoinThreshold(默认10M)且总行数低于阈值,基表不能被广播;洗牌散列连接的小表大小需小于阈值乘以分区数,且较小表至少比大表小3倍;洗牌排列合并连接要求连接键可排序;广播嵌套循环连接仅支持内连接且需开启crossJoin.enabled参数。实际应用中应提前核对这些条件,避免策略失效或性能下降。
Q&A
Spark SQL 选择连接策略时,为什么应尽量避免 shuffle 和 sort 操作?
因为 shuffle 和 sort 操作性能开销很大,比较吃资源且耗时,所以首选的连接策略是不需要 shuffle 和 sort 的 hash 连接策略。
Spark SQL 支持哪些连接提示(Join Hint)?
Spark SQL 支持四种连接提示:BROADCAST、SHUFFLE_MERGE、SHUFFLE_HASH、SHUFFLE_REPLICATE_NL。
广播散列连接(BHJ)有哪些限制条件?
BHJ 的限制条件包括:1. 被广播的小表大小必须小于参数 spark.sql.autoBroadcaseJoinThreshold(默认10M);2. 基表不能被广播,比如 left join 时只能广播右表;3. 数据集的总行数小于 MAX_BROADCAST_TABLE_ROWS 阈值(3.41亿行)。
洗牌散列连接(SHJ)在什么情况下性能可能不如洗牌排列合并连接(SMJ)?
当较小表没有至少比大表小3倍以上时,SHJ 的性能收益未必大于 SMJ,因此此时可能不如 SMJ。
哪些连接策略支持非等值连接?
只有笛卡尔积连接(CPJ)和广播嵌套循环连接(BNLJ)支持非等值连接,因为非等值连接需要对不确定值进行范围比较,需要嵌套循环。
广播嵌套循环连接(BNLJ)的使用条件是什么?
BNLJ 仅支持内连接,并且需要开启参数 spark.sql.crossJoin.enabled=true。