共用方式為


使用偏斜提示進行偏斜 join 優化

重要

此文件已停用,且可能不會更新。 不再支援此內容中所提及的產品、服務或技術。

不需要偏斜 join 的提示。 Databricks 預設會使用自適應查詢執行(AQE)來處理數據偏斜。 請參閱 調適型查詢執行

注意

spark.sql.adaptive.skewJoin.enabled 必須 True,這是 Azure Databricks 的預設設定。

什麼是數據扭曲?

資料偏斜是指 table的資料在叢集中的分割區之間分配不均。 數據偏斜可能會嚴重降低查詢的效能,特別是那些涉及連結的查詢。 大型 tables 之間的聯結需要重新分配資料,而偏斜可能會導致叢集中工作的極端不平衡。 當查詢似乎卡在只剩下少量任務無法完成時,這可能是因數據偏斜影響了查詢(例如,在 200 個任務中有最後的 3 個任務還未完成)。 若要確認資料扭曲會影響查詢:

  1. 點擊卡住的階段,並確認它正在執行 join。
  2. 查詢完成之後,尋找執行 join 的階段,並檢查工作時間分佈。
  3. 將工作按照由長至短的工期進行排序,並檢查最前面的幾個工作。 如果某個工作比其他工作花了很多時間來完成,就會有扭曲。

為了改善偏態,Azure Databricks SQL 上的 Delta Lake 在查詢中接受 偏態提示。 透過偏斜提示中的資訊,Databricks Runtime 可以建構更好的查詢計劃,而不會遭受數據偏斜。

使用關聯名稱設定偏斜提示

偏態提示至少必須包含具偏態關聯的名稱。 關係是 table、檢視或子查詢。 所有與這個關聯進行聯結的操作都將使用偏斜 join 優化。

-- table with skew
SELECT /*+ SKEW('orders') */
  *
  FROM orders, customers
  WHERE c_custId = o_custId

-- subquery with skew
SELECT /*+ SKEW('C1') */
  *
  FROM (SELECT * FROM customers WHERE c_custId < 100) C1, orders
  WHERE C1.c_custId = o_custId

使用關聯名稱和 column 名稱來設定偏斜提示

關聯上可能會有多個連接,其中只有一些連接會受到偏斜的影響。 Skew join 優化會有一些額外負擔,因此最好只在需要時才使用。 為此,Skew Hint 接受 column 名稱。 只有這些 columns 的連結使用偏斜 join 優化。

-- single column
SELECT /*+ SKEW('orders', 'o_custId') */
  *
  FROM orders, customers
  WHERE o_custId = c_custId

-- multiple columns
SELECT /*+ SKEW('orders', ('o_custId', 'o_storeRegionId')) */
  *
  FROM orders, customers
  WHERE o_custId = c_custId AND o_storeRegionId = c_regionId

使用關聯名稱、column 名稱和偏斜 values 設定偏斜提示

您也可以在提示中指定傾斜 values。 視查詢和數據而定,可能會知道扭曲 values(例如,因為它們永遠不會變更),或可能很容易發現。這樣做可減少扭曲 join 優化的額外負荷。 否則,Delta Lake 會自動偵測它們。

-- single column, single skew value
SELECT /*+ SKEW('orders', 'o_custId', 0) */
  *
  FROM orders, customers
  WHERE o_custId = c_custId

-- single column, multiple skew values
SELECT /*+ SKEW('orders', 'o_custId', (0, 1, 2)) */
  *
  FROM orders, customers
  WHERE o_custId = c_custId

-- multiple columns, multiple skew values
SELECT /*+ SKEW('orders', ('o_custId', 'o_storeRegionId'), ((0, 1001), (1, 1002))) */
  *
  FROM orders, customers
  WHERE o_custId = c_custId AND o_storeRegionId = c_regionId