当前 Spark 计算引擎能够利用一些统计信息选择合适的 Join 策略(关于 Spark 支持的 Join 策略可以参见每个 Spark 工程师都应该知道的五种 Join 策略),但是由于各种原因,比如统计信息缺失、统计信息不准确等原因,Spark 给我们选择的 Join 策略不是正确的,这时候我们就可以人为“干涉”,Spark 从 2.2.0 版本开始(参见SPARK-16475),支持在 SQL 中指定 Join Hints 来指定我们选择的 Join 策略。
Join hints 允许用户为 Spark 指定 Join 策略( join strategy)。在 Spark 3.0 之前,只支持 BROADCAST
Join Hint,到了 Spark 3.0,添加了 MERGE, SHUFFLE_HASH 以及 SHUFFLE_REPLICATE_NL Joint Hints(参见SPARK-27225、这里、这里)。当在 Join 的两端指定不同的 Join strategy hints 时,Spark 按照 BROADCAST -> MERGE -> SHUFFLE_HASH -> SHUFFLE_REPLICATE_NL 的顺序为选择 Join 策略。当 Join 的两端都指定了 BROADCAST hint 或者 SHUFFLE_HASH hint 时,Spark 将根据 relations 的大小以及 Join 的类型(join type)设置 build side。由于给定的 Join 策略并不适合所有的 Join 类型,所以 Spark 并不保证指定的 Join hint 一定会被使用。
Join Hints 类型
当前 Spark 支持以下四种 Join Hints。
BROADCAST
建议 Spark 使用 broadcast join,被 hint 指定的表将会被广播到 Executor 端,而且会忽略 autoBroadcastJoinThreshold 阈值。如果 Join 的两张表都指定了
broadcast hints,那么 Spark 会基于统计信息把小表广播出去。BROADCAST 的别名有 BROADCASTJOIN 和 MAPJOIN。
MERGE
建议 Spark 使用 shuffle sort merge join,MERGE 的其他别名有 SHUFFLE_MERGE 和 MERGEJOIN。
SHUFFLE_HASH
建议 Spark 使用 shuffle hash join。如果 Join 的两张表都指定了 shuffle hash hints ,那么 Spark 会基于统计信息将小表作为 build side。
SHUFFLE_REPLICATE_NL
建议 Spark 使用 shuffle-and-replicate nested loop join。
例子
broadcast join 的 Join Hints 有以下三种写法
SELECT /*+ BROADCAST(t1) */ * FROM t1 INNER JOIN t2 ON t1.key = t2.key;
SELECT /*+ BROADCASTJOIN (t1) */ * FROM t1 left JOIN t2 ON t1.key = t2.key;
SELECT /*+ MAPJOIN(t2) */ * FROM t1 right JOIN t2 ON t1.key = t2.key;
sort merge join 的 Join Hints 有以下三种写法
SELECT /*+ SHUFFLE_MERGE(t1) */ * FROM t1 INNER JOIN t2 ON t1.key = t2.key;
SELECT /*+ MERGEJOIN(t2) */ * FROM t1 INNER JOIN t2 ON t1.key = t2.key;
SELECT /*+ MERGE(t1) */ * FROM t1 INNER JOIN t2 ON t1.key = t2.key;
shuffle hash join 的 Join Hints 写法如下
SELECT /*+ SHUFFLE_HASH(t1) */ * FROM t1 INNER JOIN t2 ON t1.key = t2.key;
shuffle-and-replicate nested loop join 的 Join Hints 写法如下
SELECT /*+ SHUFFLE_REPLICATE_NL(t1) */ * FROM t1 INNER JOIN t2 ON t1.key = t2.key;
同时指定多个 Join Hints
-- When different join strategy hints are specified on both sides of a join, Spark
-- prioritizes the BROADCAST hint over the MERGE hint over the SHUFFLE_HASH hint
-- over the SHUFFLE_REPLICATE_NL hint.
-- Spark will issue Warning in the following example
-- org.apache.spark.sql.catalyst.analysis.HintErrorLogger: Hint (strategy=merge)
-- is overridden by another hint and will not take effect.
SELECT /*+ BROADCAST(t1), MERGE(t1, t2) */ * FROM t1 INNER JOIN t2 ON t1.key = t2.key;
本博客文章除特别声明,全部都是原创!转载本文请加上:转载自过往记忆(https://www.iteblog.com/)
本文链接: 【Spark Join Hints 简介及使用】(https://www.iteblog.com/archives/9874.html)
来源:oschina
链接:https://my.oschina.net/u/4344310/blog/4574427