提示
說明
提示提供使用者一種方式,建議 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
可用於重新平衡查詢結果輸出分割區,讓每個分割區的大小合理(不會太小或太大)。它可以將欄位名稱作為參數,並盡力依據這些欄位分割查詢結果。這是一種盡力而為的作法:如果有偏差,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
,而 MERGE
優先於 SHUFFLE_HASH
,而 SHUFFLE_HASH
優先於 SHUFFLE_REPLICATE_NL
。當兩邊都指定了 BROADCAST
提示或 SHUFFLE_HASH
提示時,Spark 會根據加入類型和關聯的大小選擇組建方。由於給定的策略可能不支援所有加入類型,因此 Spark 無法保證使用提示建議的加入策略。
加入提示類型
-
廣播
建議 Spark 使用廣播加入。無論
autoBroadcastJoinThreshold
為何,具有提示的加入方都會廣播。如果加入的兩邊都有廣播提示,則會廣播大小較小的一方(根據統計資料)。BROADCAST
的別名為BROADCASTJOIN
和MAPJOIN
。 -
合併
建議 Spark 使用洗牌排序合併聯結。
MERGE
的別名為SHUFFLE_MERGE
和MERGEJOIN
。 -
SHUFFLE_HASH
建議 Spark 使用洗牌雜湊聯結。如果兩側都有洗牌雜湊提示,Spark 會根據統計資料選擇較小的一側作為建置側。
-
SHUFFLE_REPLICATE_NL
建議 Spark 使用洗牌和複製巢狀迴圈聯結。
範例
-- 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;