使用扭曲提示的扭曲聯結優化

本文說明如何使用扭曲提示來改善數據表中的數據扭曲,這是可降級查詢效能的條件。

注意

不需要扭曲聯結提示。 如果調適型查詢執行 (AQE) 且 spark.sql.adaptive.skewJoin.enabled 都已啟用,則會自動處理扭曲。 請參閱 調適型查詢執行

什麼是數據扭曲?

資料扭曲是資料表資料不平均分散在叢集中資料分割的條件。 資料扭曲可能會嚴重降級查詢的效能,特別是具有聯結的資料扭曲。 大型數據表之間的聯結需要洗牌數據,而扭曲可能會導致叢集中工作的極端不平衡。 如果查詢似乎停滯於完成很少的工作,則數據扭曲可能會影響查詢(例如,200 個工作的最後 3 個工作)。 若要確認資料扭曲會影響查詢:

  1. 按兩下停滯的階段,並確認它正在執行聯結。
  2. 查詢完成之後,尋找執行聯結的階段,並檢查工作持續時間分佈。
  3. 藉由減少持續時間來排序工作,並檢查前幾個工作。 如果某個工作花費的時間比其他工作還長,就會有扭曲。

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

使用關聯名稱設定扭曲提示

扭曲提示至少必須包含具有扭曲之關聯的名稱。 關聯性是數據表、檢視或子查詢。 使用此關聯的所有聯結,然後使用扭曲聯結優化。

-- 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

使用關聯名稱和數據行名稱設定扭曲提示

關聯上可能會有多個聯結,其中只有一些聯結會受到扭曲。 扭曲聯結優化有一些額外負荷,因此最好只在需要時才使用它。 為此,扭曲提示會接受數據行名稱。 只有與這些數據行聯結的聯結會使用扭曲聯結優化。

-- 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

使用關聯名稱、數據行名稱和扭曲值設定扭曲提示

您也可以在提示中指定扭曲值。 視查詢和數據而定,扭曲值可能已知(例如,因為它們永遠不會變更),或可能很容易找出。這樣做可減少扭曲聯結優化的額外負荷。 否則,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