共用方式為


彈性查詢執行

彈性查詢執行 (AQE) 是在查詢執行期間所進行的查詢重新最佳化。

執行時間重新優化的動機是,Azure Databricks 在洗牌和廣播交換結束時擁有最新的準確統計資料(稱為 AQE 中的查詢階段)。 因此,Azure Databricks 可以選擇更好的實體策略、挑選最佳的隨機亂數據分割大小和數位,或執行需要提示的優化,例如扭曲聯結處理。

當統計資料集合未開啟或統計資料過時時,這非常有用。 在靜態衍生統計資料不正確的地方也很有用,例如在複雜的查詢中間,或在發生資料扭曲之後。

功能

預設會啟用 AQE。 它有 4 個主要功能:

  • 動態變更將合併聯結排序為廣播雜湊聯結。
  • 隨機交換後,動態合併分割區(將小型分割區合併成合理大小的分割區)。 非常小型的工作有更差的 I/O 輸送量,而且往往遭受更多排程額外負荷和工作設定額外負荷。 結合小型工作可節省資源並改善叢集輸送量。
  • 動態處理排序合併聯結和隨機雜湊聯結的扭曲,方法是將扭曲的工作分割(並視需要複寫)扭曲成大致平均大小的工作。
  • 以動態方式偵測並傳播空關聯性。

應用程式

AQE 適用于下列所有查詢:

  • 非串流
  • 包含至少一個交換(通常是有聯結、匯總或視窗)、一個子查詢或兩者。

並非所有 AQE 套用的查詢都必須重新優化。 重新優化可能或可能不會想出與靜態編譯不同的查詢計劃。 若要判斷 AQE 是否已變更查詢的計畫,請參閱下列<查詢計劃 >一節

查詢計劃

本節討論如何以不同方式檢查查詢計劃。

本節內容:

Spark UI

AdaptiveSparkPlan 節點

AQE 套用的查詢包含一或多個 AdaptiveSparkPlan 節點,通常是每個主要查詢或子查詢的根節點。 在查詢執行之前或執行時, isFinalPlan 對應的 AdaptiveSparkPlan 節點旗標會顯示為 false ;查詢執行完成之後,旗標會 isFinalPlan 變更為 true.

不斷演進的計畫

查詢計劃圖表會隨著執行進度而演進,並反映正在執行的最新計畫。 已經執行的節點(可用的計量)不會變更,但因重新優化而無法隨著時間變更的節點。

以下是查詢計劃圖表範例:

Query plan diagram

DataFrame.explain()

AdaptiveSparkPlan 節點

AQE 套用的查詢包含一或多個 AdaptiveSparkPlan 節點,通常是每個主要查詢或子查詢的根節點。 在查詢執行之前或正在執行時, isFinalPlan 對應 AdaptiveSparkPlan 節點的旗標會顯示為 false ;在查詢執行完成之後,旗標會 isFinalPlan 變更為 true

目前和初始計畫

在每個 AdaptiveSparkPlan 節點下,都會有初始計畫(在套用任何 AQE 優化之前的計畫)和目前的或最終計畫,視執行是否已完成而定。 目前的計畫會隨著執行進度而發展。

執行時間統計資料

每個隨機播放和廣播階段都包含資料統計資料。

在階段執行或階段執行之前,統計資料是編譯時間估計值,而旗標 isRuntimefalse ,例如: Statistics(sizeInBytes=1024.0 KiB, rowCount=4, isRuntime=false);

階段執行完成之後,統計資料是在執行時間收集的統計資料,而旗標 isRuntime 將會變成 true ,例如: Statistics(sizeInBytes=658.1 KiB, rowCount=2.81E+4, isRuntime=true)

以下是範例 DataFrame.explain

  • 執行之前

    Before execution

  • 執行期間

    During execution

  • 執行之後

    After execution

SQL EXPLAIN

AdaptiveSparkPlan 節點

AQE 套用的查詢包含一或多個 AdaptiveSparkPlan 節點,通常是每個主要查詢或子查詢的根節點。

沒有目前的方案

由於 SQL EXPLAIN 不會執行查詢,目前的計畫一律與初始計畫相同,而且不會反映 AQE 最終會執行的專案。

以下是 SQL 說明範例:

SQL explain

有效性

如果一或多個 AQE 優化生效,查詢計劃將會變更。 這些 AQE 優化的效果會以目前和最終計畫與初始計畫與目前和最終方案中的特定計劃節點之間的差異來示範。

  • 動態變更排序合併聯結成廣播雜湊聯結:目前/最終計畫與初始計畫之間的不同實體聯結節點

    Join strategy string

  • 動態聯合資料分割:具有 屬性的節點 CustomShuffleReaderCoalesced

    Custom shuffle reader

    Custom shuffle reader string

  • 動態處理扭曲聯結:具有欄位 isSkew 為 true 的節點 SortMergeJoin

    Skew join plan

    Skew join string

  • 動態偵測和傳播空白關聯:計畫的一部分會由 node LocalTableScan 取代為空白的關聯欄位。

    Local table scan

    Local table scan string

組態

本節內容:

啟用和停用調適型查詢執行

屬性
spark.databricks.optimizer.adaptive.enabled

類型:Boolean (英文)

是否要啟用或停用調適型查詢執行。

預設值:true

啟用自動優化的隨機顯示

屬性
spark.sql.shuffle.partitions

類型:Integer (英文)

隨機顯示聯結或匯總資料時要使用的預設分割區數目。 設定值 auto 可啟用自動優化的隨機顯示,這會自動根據查詢計劃和查詢輸入資料大小來決定這個數位。

注意:針對結構化串流,此設定無法在查詢從相同檢查點位置重新開機之間變更。

預設值:200

將排序合併聯結動態變更為廣播雜湊聯結

屬性
spark.databricks.adaptive.autoBroadcastJoinThreshold

類型:Byte String (英文)

觸發切換至執行時間廣播聯結的臨界值。

預設值:30MB

動態聯合資料分割

屬性
spark.sql.adaptive.coalescePartitions.enabled

類型:Boolean (英文)

是否啟用或停用資料分割聯合。

預設值:true
spark.sql.adaptive.advisoryPartitionSizeInBytes

類型:Byte String (英文)

聯合之後的目標大小。 合併的資料分割大小將會接近,但不會大於此目標大小。

預設值:64MB
spark.sql.adaptive.coalescePartitions.minPartitionSize

類型:Byte String (英文)

合併後的分割區大小下限。 合併的資料分割大小不會小於此大小。

預設值:1MB
spark.sql.adaptive.coalescePartitions.minPartitionNum

類型:Integer (英文)

聯合之後的資料分割數目下限。 不建議使用,因為設定會明確覆寫
spark.sql.adaptive.coalescePartitions.minPartitionSize.

預設值:2x no。叢集核心的

動態處理扭曲聯結

屬性
spark.sql.adaptive.skewJoin.enabled

類型:Boolean (英文)

是否啟用或停用扭曲聯結處理。

預設值:true
spark.sql.adaptive.skewJoin.skewedPartitionFactor

類型:Integer (英文)

乘以中位數資料分割大小的因素,有助於判斷分割區是否扭曲。

預設值:5
spark.sql.adaptive.skewJoin.skewedPartitionThresholdInBytes

類型:Byte String (英文)

導致判斷分割區是否扭曲的臨界值。

預設值:256MB

當 和 (partition size > skewedPartitionThresholdInBytes) true 都是 (partition size > skewedPartitionFactor * median partition size) 時,分割區會被視為扭曲。

動態偵測和傳播空白關聯

屬性
spark.databricks.adaptive.emptyRelationPropagation.enabled

類型:Boolean (英文)

是否啟用或停用動態空白關聯傳播。

預設值:true

常見問題集 (FAQ)

本節內容:

為什麼 AQE 不會廣播小型聯結資料表?

如果預期要廣播的關聯大小落在此臨界值之下,但仍不會廣播:

  • 檢查聯結類型。 某些聯結類型不支援廣播,例如,無法廣播 的 LEFT OUTER JOIN 左關聯性。
  • 也可能是關聯包含許多空白資料分割,在此情況下,大部分工作都可以使用排序合併聯結快速完成,或者可能會使用扭曲聯結處理進行優化。 如果非空白資料分割的百分比低於 spark.sql.adaptive.nonEmptyPartitionRatioForBroadcastJoin ,AQE 可避免將這類排序合併聯結變更為廣播雜湊聯結。

我是否仍應使用已啟用 AQE 的廣播聯結策略提示?

是。 靜態規劃的廣播聯結通常比 AQE 動態規劃的廣播聯結更有效能,因為 AQE 在為聯結的兩端執行洗牌之前,可能不會切換為廣播聯結(屆時取得實際關聯大小)。 因此,如果您非常瞭解您的查詢,使用廣播提示仍然可以是不錯的選擇。 AQE 會採用與靜態優化相同的查詢提示,但仍可以套用不受提示影響的動態優化。

扭曲聯結提示與 AQE 扭曲聯結優化有何差異? 我應該使用哪一個?

建議依賴 AQE 扭曲聯結處理,而不是使用扭曲聯結提示,因為 AQE 扭曲聯結是完全自動的,而且一般執行效能優於提示對應專案。

為什麼 AQE 不會自動調整我的聯結順序?

動態聯結重新排序不是 AQE 的一部分。

為什麼 AQE 偵測到我的資料扭曲?

AQE 必須滿足兩個大小條件,才能將分割區偵測為扭曲的資料分割:

  • 分割區大小大於 spark.sql.adaptive.skewJoin.skewedPartitionThresholdInBytes (預設值 256MB)
  • 分割區大小大於扭曲資料分割因數 spark.sql.adaptive.skewJoin.skewedPartitionFactor 時所有分割區的中位數大小(預設值 5)

此外,特定聯結類型的扭曲處理支援有限,例如,在 中 LEFT OUTER JOIN ,只能優化左側的扭曲。

舊版

自 Spark 1.6 以來,已有「自適性執行」一詞存在,但 Spark 3.0 中的新 AQE 基本上不同。 就功能而言,Spark 1.6 只會執行「動態聯合分割區」部分。 就技術架構而言,新的 AQE 是以執行時間統計資料為基礎的動態規劃和重新規劃查詢架構,可支援各種優化,例如本文所述的優化,並可擴充以啟用更多潛在的優化。