提示
描述
提示为用户提供了一种方法,可以建议 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
连接提示。 MERGE
、SHUFFLE_HASH
和 SHUFFLE_REPLICATE_NL
连接提示支持在 3.0 中添加。当在连接的两侧指定不同的连接策略提示时,Spark 按以下顺序优先考虑提示:BROADCAST
优先于 MERGE
优先于 SHUFFLE_HASH
优先于 SHUFFLE_REPLICATE_NL
。当两侧都指定了 BROADCAST
提示或 SHUFFLE_HASH
提示时,Spark 将根据连接类型和关系的大小选择构建侧。由于给定的策略可能不支持所有连接类型,因此 Spark 不保证使用提示建议的连接策略。
连接提示类型
-
BROADCAST
建议 Spark 使用广播连接。无论
autoBroadcastJoinThreshold
如何,具有提示的连接侧都将被广播。如果连接的两侧都有广播提示,则大小较小的一侧(基于统计信息)将被广播。BROADCAST
的别名为BROADCASTJOIN
和MAPJOIN
。 -
MERGE
建议 Spark 使用 shuffle 排序合并连接。
MERGE
的别名为SHUFFLE_MERGE
和MERGEJOIN
。 -
SHUFFLE_HASH
建议 Spark 使用 shuffle 哈希连接。如果两侧都有 shuffle 哈希提示,Spark 会选择较小的一侧(基于统计信息)作为构建侧。
-
SHUFFLE_REPLICATE_NL
建议 Spark 使用 shuffle 和复制嵌套循环连接。
示例
-- 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;