適用於:✅ 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。 - 欄位排序或設定變更可能需要全面刷新。