這兩天在SparkSQL Core看到一個優(yōu)化規(guī)則:OptimizeMetadataOnlyQuery谊路,它的意思是如果一個sql只涉及表的分區(qū)字段元信息查詢的話末融,執(zhí)行過程將不會路由到TableScanExec的PhysicalPlan進行表掃描捺萌,而是通過分區(qū)元信息的字段和值構建LocalRelation拟枚,進而構造一個LocalTable休吠,走LocalTableScanExec的PhysicalPlan谒获。
這個規(guī)則的觸發(fā)要滿足下面幾個條件:
- sql中所有查詢的字段必須是分區(qū)字段
- 如果使用了聚合函數(shù)蛤肌,必須滿足下面條件:
- 聚合表達式是分區(qū)字段,如(col等為tbl的分區(qū)字段批狱,下同):
SELECT col FROM tbl GROUP BY col. - 對分區(qū)字段使用的聚合函數(shù)帶Distinct裸准,如:
SELECT count(DISTINCT col) FROM tbl GROUP BY col. - 對分區(qū)字段使用的聚合函數(shù)為Max,Min赔硫,F(xiàn)irst炒俱、Last函數(shù),如:
SELECT Max(col) FROM tbl GROUP BY col.
- 聚合表達式是分區(qū)字段,如(col等為tbl的分區(qū)字段批狱,下同):
如果滿足上面的條件爪膊,將會對邏輯計劃進行優(yōu)化权悟,調(diào)用replaceTableScanWithPartitionMetadata,做的事情包括:
1. 把CatalogTable中的分區(qū)字段取出來推盛;
2. 把CatalogTable中的分區(qū)值取出來峦阁;
3. 構建LocalRelation(partAttrs, partitionData)
簡單來說,就是把分區(qū)字段及其值取出來耘成,構造一個本地表榔昔,這樣在執(zhí)行時就不需要去掃描真正的表了。
如果要禁用該優(yōu)化瘪菌,需要設置參數(shù)spark.sql.optimizer.metadataOnly=false
撒会,spark里面默認是true。