提示
描述
提示给用户提供了一种建议如何使用特定方法生成Spark SQL的执行计划的方式。
语法
/*+ 提示 [ , ... ] */
分区提示
分区提示允许用户建议Spark应遵循的分区策略。
COALESCE
、
REPARTITION
和
REPARTITION_BY_RANGE
提示是支持的,分别等同于
coalesce
、
repartition
和
repartitionByRange
Dataset APIs
。
REBALANCE
只能作为提示使用。这些提示为用户提供了一种调整性能和控制Spark SQL中输出文件数量的方法。当指定多个分区提示时,多个节点被插入到逻辑计划中,但优化器选择最左侧的提示。
分区提示类型
-
COALESCE
COALESCE
提示可以用于减少分区数量到指定的分区数。它将分区数量作为参数。 -
REPARTITION
REPARTITION
提示可以用于使用指定的分区表达式重新分区到指定的分区数量。它将分区数量、列名或两者作为参数。 -
REPARTITION_BY_RANGE
REPARTITION_BY_RANGE
提示可以用于使用指定的分区表达式重新分区到指定的分区数量。它将列名和一个可选的分区数量作为参数。 -
REBALANCE
REBALANCE
提示可以用于重新平衡查询结果输出分区,以便每个分区都是合理大小(不太小也不太大)。它可以将列名作为参数,并努力根据这些列对查询结果进行分区。这是一种尽力而为的方法:如果存在偏差,Spark将拆分偏斜的分区,以确保这些分区不太大。当您需要将此查询的结果写入表中以避免过小/过大的文件时,此提示非常有用。如果未启用AQE,则该提示将被忽略。
示例
SELECT /*+ COALESCE(3) */ * FROM t;
SELECT /*+ REPARTITION(3) */ * FROM t;
SELECT /*+ REPARTITION(c) */ * FROM t;
SELECT /*+ REPARTITION(3, c) */ * FROM t;
SELECT /*+ REPARTITION_BY_RANGE(c) */ * FROM t;
SELECT /*+ REPARTITION_BY_RANGE(3, c) */ * FROM t;
SELECT /*+ REBALANCE */ * FROM t;
SELECT /*+ REBALANCE(3) */ * FROM t;
SELECT /*+ REBALANCE(c) */ * FROM t;
SELECT /*+ REBALANCE(3, c) */ * FROM t;
-- 多个分区提示
EXPLAIN EXTENDED SELECT /*+ REPARTITION(100), COALESCE(500), REPARTITION_BY_RANGE(3, c) */ * FROM t;
== 解析 逻辑 计划 ==
'未解析的提示 REPARTITION, [100]
+- '未解析的提示 COALESCE, [500]
+- '未解析的提示 REPARTITION_BY_RANGE, [3, 'c]
+- '项目 [*]
+- '未解析的关系 [t]
== 分析 逻辑 计划 ==
name: string, c: int
Repartition 100, true
+- Repartition 500, false
+- RepartitionByExpression [c#30 ASC NULLS FIRST], 3
+- 项目 [name#29, c#30]
+- 子查询别名 spark_catalog.default.t
+- 关系[name#29,c#30] parquet
== 优化的 逻辑 计划 ==
Repartition 100, true
+- 关系[name#29,c#30] parquet
== 物理 计划 ==
交换 轮询分区(100), false, [id=#121]
+- *(1) 列到行
+- 文件扫描 parquet default.t[name#29,c#30] 批量: true, 数据过滤器: [], 格式: Parquet,
位置: CatalogFileIndex[file:/spark/spark-warehouse/t], 分区过滤器: [],
推送的过滤器: [], 读取模式: 结构<name:string>
连接提示
连接提示允许用户建议Spark应该使用的连接策略。在Spark 3.0之前,仅支持
BROADCAST
连接提示。
MERGE
、
SHUFFLE_HASH
和
SHUFFLE_REPLICATE_NL
连接提示的支持是在3.0中添加的。当在连接的两边指定不同的连接策略提示时,Spark优先考虑以下顺序:
BROADCAST
优先于
MERGE
,优先于
SHUFFLE_HASH
,优先于
SHUFFLE_REPLICATE_NL
。当两边都指定了
BROADCAST
提示或
SHUFFLE_HASH
提示时,Spark会根据连接类型和关系的大小选择构建侧。由于给定的策略可能不支持所有连接类型,因此Spark不保证使用提示中建议的连接策略。
连接提示类型
-
广播
建议Spark使用广播连接。带有提示的连接侧会被广播,无论
autoBroadcastJoinThreshold
的设置如何。如果连接的两个侧都有广播提示,则将基于统计信息广播较小的那一侧。BROADCAST
的别名是BROADCASTJOIN
和MAPJOIN
。 -
合并
建议Spark使用洗牌排序合并连接。
MERGE
的别名是SHUFFLE_MERGE
和MERGEJOIN
。 -
洗牌哈希
建议Spark使用洗牌哈希连接。如果两个侧都有洗牌哈希提示,Spark会选择较小的那一侧(基于统计信息)作为构建侧。
-
洗牌复制嵌套循环
建议Spark使用洗牌和复制的嵌套循环连接。
示例
-- 广播连接的连接提示
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;
-- 洗牌排序合并连接的连接提示
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;
-- 洗牌哈希连接的连接提示
SELECT /*+ SHUFFLE_HASH(t1) */ * FROM t1 INNER JOIN t2 ON t1.key = t2.key;
-- 洗牌和复制嵌套循环连接的连接提示
SELECT /*+ SHUFFLE_REPLICATE_NL(t1) */ * FROM t1 INNER JOIN t2 ON t1.key = t2.key;
-- 当在连接的两边指定不同的连接策略提示时,Spark
-- 优先考虑 BROADCAST 提示,其次是 MERGE 提示,然后是 SHUFFLE_HASH 提示
-- 以及 SHUFFLE_REPLICATE_NL 提示。
-- 在以下示例中,Spark 会发出警告
-- org.apache.spark.sql.catalyst.analysis.HintErrorLogger: 提示 (strategy=merge)
-- 被另一个提示覆盖,将不会生效。
SELECT /*+ BROADCAST(t1), MERGE(t1, t2) */ * FROM t1 INNER JOIN t2 ON t1.key = t2.key;