[英]Why would finding an aggregate of a partition column in Spark 3 take very long time?
我正在嘗試在 Spark2 和 Spark3 中使用以下查詢查詢按dt
列分區的表中的MIN(dt)
:
SELECT MIN(dt) FROM table_name
該表以 parquet 格式存儲在 S3 中,其中每個dt
都是一個單獨的文件夾,因此這似乎是一個非常簡單的操作。 大約有 3,200 天的數據。
在 Spark2 中,這個查詢在大約 1 分鍾內完成,而在 Spark3 中,查詢需要一個多小時(不確定具體多長時間,因為它還沒有完成)。
在Spark3中,執行計划是:
AdaptiveSparkPlan (10)
+- == Current Plan ==
HashAggregate (6)
+- ShuffleQueryStage (5)
+- Exchange (4)
+- * HashAggregate (3)
+- * ColumnarToRow (2)
+- Scan parquet table_name (1)
+- == Initial Plan ==
HashAggregate (9)
+- Exchange (8)
+- HashAggregate (7)
+- Scan parquet table_name (1)
我很困惑這會花很長時間,因為數據已經被dt
分區了。 Spark 只需要確定哪些分區有任何行並返回這些行的最小值。
您的建議是通過 JIRA SPARK-15752 “優化僅元數據查詢,其子項是確定性項目或過濾器運算符的聚合”作為OptimizeMetadataOnly
查詢優化器規則實施過一次。
但是,當某些分區包含零行文件時,發現有時會導致正確性問題,請參閱 JIRA SPARK-26709 “OptimizeMetadataOnlyQuery 無法正確處理具有零記錄的文件”。
除了修復之外,還添加了一個內部 Spark 配置spark.sql.optimizer.metadataOnly
以提供一種方法來規避全表掃描,“風險自負”,即當您確定所有分區都不為空時。 可能,在您的 Spark 2 中,您已將其設置為true
(或者您的 Spark 2 根本不包含修復程序)。 另請參閱SPARK-34194了解有關它的更多討論。
SPARK 3.0 棄用了此配置 ( SPARK-31647 ),因此它很可能在您的環境中設置為false
,這會導致 Spark 在聚合結果以查找min
之前掃描所有表分區。 不過暫時還是可以嘗試將其設置為true
來加快查詢速度,注意后果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.