在網狀架構 Spark 中設定和管理自動化數據表統計數據

適用於:✅ Fabric 資料工程與資料科學

Microsoft Fabric 中的自動資料表統計協助 Spark 優化查詢執行,自動收集 Delta 資料表的表與欄指標。

  • 列計數
  • 每欄的無計數。
  • 每欄的最小值與最大值。
  • 每欄有不同的數值。
  • 平均與最大柱長。

預設情況下,這些擴展統計資料會收集 Fabric 中 Delta 表格的前 32 欄(含巢狀欄位)。 這些數據幫助 Spark 的成本基礎優化器(CBO)改善連接、篩選、聚合與分割剪枝的規劃。

因此,許多工作負載能降低查詢延遲並降低計算使用率,減少手動統計維護。

關於跨工作負載的表格優化策略指引,請參見 跨工作負載資料表維護與優化。

主要優點

自動化統計帶來以下好處:

  • 在 Fabric 中自動啟用 Delta 表格。
  • 提升常見分析模式的查詢規劃品質。
  • 減少了重複手動統計資料收集的需求。
  • 將統計資料儲存在資料表檔案之外,以避免資料檔案膨脹。

運作方式

Fabric Spark 在寫入時收集擴展統計資料,並在規劃時使用。

收藏範圍與行為:

  • 統計數據會在寫入時收集。
  • 收集目標為前 32 欄位(含巢狀欄位)。
  • 資料表屬性可以覆蓋會話層級的行為。
  • 配置控制 Spark 是否將統計資料注入優化器。

這些指標幫助 Spark 選擇更好的加入策略、改善分割區修剪,並優化聚合計畫。

啟用或停用統計資料收集

使用會話設定(工作區或筆記本範圍)或資料表屬性(每個資料表的範圍)。

會話設定

您可以在會話層級啟用或停用擴展統計資料收集和優化器插入。

這些設定可以透過 Spark SQL、PySpark 或 Scala Spark 來套用。

執行以下 Spark SQL 語句以啟用集合與優化器注入:

SET spark.microsoft.delta.stats.collect.extended=true;
SET spark.microsoft.delta.stats.injection.enabled=true;

要停用任一設定,請使用相同的指令,並將值設為 false。

備註

必須啟用記錄統計資料收集(spark.databricks.delta.stats.collect)(預設值:true)。

Important

如果你在某個表格上啟用 刪除向量 ,請關閉該表格的統計注入。 在使用刪除向量且頻繁更新或刪除的資料表中,擴充統計資料可能變得不準確,導致 Spark 低估資料表大小。 此時,優化器可能會選擇不合適的廣播連接,導致查詢失敗。 為避免此行為,請關閉統計注入,避免優化器使用注入的統計資料:

  • 會話範圍:設 spark.microsoft.delta.stats.injection.enabled 為 false。
  • 表格範圍:將表格屬性設 delta.stats.extended.inject 為 false。

你可以繼續開啟統計資料收集。 對於使用刪除向量的資料表,只需停用注入至最佳化器的功能。

定期的資料表維護策略可降低這種風險。 OPTIMIZE 會自動清除刪除向量參考超過 5% 列的檔案, REORG TABLE ... APPLY (PURGE) 並可能強制重寫低於該門檻。 由於擴充統計資料是在寫入時收集,重寫會刷新受影響檔案的統計資料。 對於頻繁更新或刪除的資料表,請在維護週期之間關閉注入功能。

Table 屬性(覆寫會話設定)

資料表屬性可讓您控制個別資料表的統計資料收集,並覆蓋會話設定。

在資料表上啟用:

ALTER TABLE tableName
SET TBLPROPERTIES(
    'delta.stats.extended.collect' = 'true',
    'delta.stats.extended.inject' = 'true'
)

要停用任一資料表屬性,請將其值設為 false。

資料表建立的預設行為

使用這個會話層級設定,當建立新資料表時,禁用自動標記統計資料表的擴充屬性。

請使用這個 Spark SQL 語句來關閉建立資料表時的自動設定:

SET spark.microsoft.delta.stats.collect.extended.property.setAtTableCreation=false;

查看統計數據

你可以透過 Spark API 檢視優化查詢計畫可用的統計資料。 這些 API 會從任何可用來源(包括 Spark 目錄統計)回傳通用計畫統計。 某個結果並不表示已針對該資料表收集 Fabric 的延伸統計資料。

檢查資料列計數和資料表大小 (Scala 範例):

println(spark.read.table("tableName").queryExecution.optimizedPlan.stats)

檢查詳細資料欄統計資料。

val stats = spark.read.table("tableName").queryExecution.optimizedPlan.stats

stats.attributeStats.foreach { case (attrName, colStat) =>
    println(s"colName: $attrName distinctCount: ${colStat.distinctCount} min: ${colStat.min} max: ${colStat.max} nullCount: ${colStat.nullCount} avgLen: ${colStat.avgLen} maxLen: ${colStat.maxLen}")
}

重新計算統計量

統計資料在結構變更或部分更新後可能會過時。 請使用以下其中一種方法來重新計算。

重寫數據表(注意:這會重設歷程記錄):

spark.read.table("targetTable").write.partitionBy("partCol").mode("overwrite").saveAsTable("targetTable")

建議的方法 (Fabric Spark >= 3.2.0.19):

from pyspark.sql.delta import StatisticsStore

StatisticsStore.recomputeStatisticsWithCompaction(spark, "testTable1")

如果結構改變(例如新增或刪除欄位),請先移除舊統計資料再重新計算:

from pyspark.sql.delta import StatisticsStore

StatisticsStore.removeStatisticsData(spark, "testTable1")
StatisticsStore.recomputeStatisticsWithCompaction(spark, "testTable1")

使用「ANALYZE TABLE」命令(分析表)

使用 ANALYZE TABLE 來計算 Spark 目錄中所有欄位的統計資料。 這個指令不會重新計算自動表格統計所儲存的擴展統計數據。 若要重新計算這些統計量,請使用 StatisticsStore.recomputeStatisticsWithCompaction。

執行命令:

執行以下 Spark SQL 陳述句:

ANALYZE TABLE tableName COMPUTE STATISTICS FOR ALL COLUMNS

開啟目錄統計資料插入:

請使用此 Spark SQL 陳述式來啟用目錄統計注入:

SET spark.microsoft.delta.stats.injection.catalog.enabled=true;

要停用目錄統計注入,請使用相同的設定,並將值設為 false。

局限性

請務必瞭解 Fabric 自動化統計數據的目前限制,以便您可以據以規劃。

  • 統計資料僅在寫入時收集。
  • 來自其他引擎的更新不會自動彙整。
  • 僅包含前 32 個欄位(包括巢狀欄位)。
  • 刪除和更新會讓統計數據變得陳舊。 對於使用刪除向量的資料表,定期 OPTIMIZE 或 REORG TABLE ... APPLY (PURGE) 維護會重寫受影響的檔案並刷新其統計資料。 在頻繁更新或刪除的資料表中,關閉維護週期間的統計注入。
  • 重新計算需要重寫或統計 API 操作。
  • 統計注入不適用於巢狀欄位。
  • 在某些工作負載中,過時或不完整的統計數據可能導致退步。
  • ANALYZE TABLE 支援範圍限制於 FOR ALL COLUMNS。
  • 欄位排序或設定變更可能需要全面刷新。