提示
描述
提示为用户提供了一种建议 Spark SQL 如何使用特定方法来生成其执行计划的方式。
语法
/*+ hint [ , ... ] */
分区提示
分区提示允许用户建议 Spark 应遵循的分区策略。 支持COALESCE
,REPARTITION
和REPARTITION_BY_RANGE
提示,并且分别等效于coalesce
,repartition
和repartitionByRange
Dataset API。 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;
-- multiple partitioning hints
EXPLAIN EXTENDED SELECT /*+ REPARTITION(100), COALESCE(500), REPARTITION_BY_RANGE(3, c) */ * FROM t;
== Parsed Logical Plan ==
'UnresolvedHint REPARTITION, [100]
+- 'UnresolvedHint COALESCE, [500]
+- 'UnresolvedHint REPARTITION_BY_RANGE, [3, 'c]
+- 'Project [*]
+- 'UnresolvedRelation [t]
== Analyzed Logical Plan ==
name: string, c: int
Repartition 100, true
+- Repartition 500, false
+- RepartitionByExpression [c#30 ASC NULLS FIRST], 3
+- Project [name#29, c#30]
+- SubqueryAlias spark_catalog.default.t
+- Relation[name#29,c#30] parquet
== Optimized Logical Plan ==
Repartition 100, true
+- Relation[name#29,c#30] parquet
== Physical Plan ==
Exchange RoundRobinPartitioning(100), false, [id=#121]
+- *(1) ColumnarToRow
+- FileScan parquet default.t[name#29,c#30] Batched: true, DataFilters: [], Format: Parquet,
Location: CatalogFileIndex[file:/spark/spark-warehouse/t], PartitionFilters: [],
PushedFilters: [], ReadSchema: struct<name:string>
连接提示
连接提示允许用户建议 Spark 应使用的连接策略。 在 Spark 3.0 之前,仅支持BROADCAST
连接提示。 在 3.0 中添加了MERGE
,SHUFFLE_HASH
和SHUFFLE_REPLICATE_NL
联合提示支持。 如果在连接的两侧指定了不同的连接策略提示,则Spark会按以下顺序优先考虑提示:BROADCAST
高于MERGE
高于SHUFFLE_HASH
高于SHUFFLE_REPLICATE_NL
。 如果使用BROADCAST
提示或SHUFFLE_HASH
提示指定了两侧,则Spark将根据连接类型和关系的大小选择构建侧。 由于给定的策略可能不支持所有连接类型,因此不能保证 Spark 会使用提示建议的连接策略。
连接提示类型
-
BROADCAST
建议 Spark 使用广播连接。 具有提示的连接侧将广播,而与
autoBroadcastJoinThreshold
无关。 如果连接的两侧都具有广播提示,则将广播尺寸较小的一侧(基于统计信息)。BROADCAST
的别名是BROADCASTJOIN
和MAPJOIN
。 -
MERGE
建议 Spark 使用 shuffle sort merge join。
MERGE
的别名是SHUFFLE_MERGE
和MERGEJOIN
。 -
SHUFFLE_HASH
建议 Spark 使用 shuffle hash join。 如果两边都有 shuffle hash 提示,Spark 会选择较小的一边(基于统计信息)作为构建端。
-
SHUFFLE_REPLICATE_NL
建议 Spark 使用 shuffle-and-replicate nested loop join。
示例
-- Join Hints for broadcast join
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;
-- Join Hints for shuffle sort merge join
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;
-- Join Hints for shuffle hash join
SELECT /*+ SHUFFLE_HASH(t1) */ * FROM t1 INNER JOIN t2 ON t1.key = t2.key;
-- Join Hints for shuffle-and-replicate nested loop join
SELECT /*+ SHUFFLE_REPLICATE_NL(t1) */ * FROM t1 INNER JOIN t2 ON t1.key = t2.key;
-- 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;