2017-09-14 79 views
1

我正在使用Spark SQL查詢Hive中的數據。數據被分區並且Spark SQL在查詢時正確地修剪分區。如何列出Hive表的分區修剪輸入?

但是,我需要列出源表以及分區過濾器或特定的輸入文件(.inputFiles將是明顯的選擇,但它不反映修剪)給定的查詢,以確定哪個部分計算將發生的數據。

我能夠得到的最接近的是通過調用df.queryExecution.executedPlan.collectLeaves()。這包含相關的計劃節點爲HiveTableScanExec實例。但是,對於org.apache.spark.sql.hive包,此類別爲private[hive]。我認爲相關領域是relationpartitionPruningPred

有什麼辦法可以達到這個目的嗎?

更新:我能得到的相關信息感謝亞採的建議,並通過使用返回relationgetHiveQlPartitions並提供partitionPruningPred作爲參數:

scan.findHiveTables(execPlan).flatMap(e => e.relation.getHiveQlPartitions(e.partitionPruningPred)) 

這包含了所有我需要的數據,包括所有輸入文件的路徑,正確分區修剪。

回答

0

那麼,你需要查詢執行的低級細節,並且事情在那裏是顛簸的。 您已收到警告:)

正如您在註釋中所述,所有執行信息均在此private[hive] HiveTableScanExec中。得到一些洞察HiveTableScanExec物理運算符(即在執行時蜂房表)

一種方法是在org.apache.spark.sql.hive包不是private[hive]創造一種後門。

package org.apache.spark.sql.hive 

import org.apache.spark.sql.hive.execution.HiveTableScanExec 
object scan { 
    def findHiveTables(execPlan: org.apache.spark.sql.execution.SparkPlan) = execPlan.collect { case hiveTables: HiveTableScanExec => hiveTables } 
} 

更改代碼以滿足您的需求。

隨着scan.findHiveTables,我通常使用:paste -raw而在spark-shell潛入這樣的「未知領域」。

你可以那麼只需做到以下幾點:

scala> spark.version 
res0: String = 2.4.0-SNAPSHOT 

// Create a Hive table 
import org.apache.spark.sql.types.StructType 
spark.catalog.createTable(
    tableName = "h1", 
    source = "hive", // <-- that makes for a Hive table 
    schema = new StructType().add($"id".long), 
    options = Map.empty[String, String]) 

// select * from h1 
val q = spark.table("h1") 
val execPlan = q.queryExecution.executedPlan 
scala> println(execPlan.numberedTreeString) 
00 HiveTableScan [id#22L], HiveTableRelation `default`.`h1`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [id#22L] 

// Use the above code and :paste -raw in spark-shell 

import org.apache.spark.sql.hive.scan 
scala> scan.findHiveTables(execPlan).size 
res11: Int = 1 

relation場是巢表後,它一直使用星火分析儀使用,以解決數據源和蜂巢表ResolveRelationsFindDataSourceTable邏輯規則解決。

通過使用ExternalCatalog接口,您可以獲得幾乎所有Spark使用的來自Hive Metastore的所有信息,該接口可用作spark.sharedState.externalCatalog。這使您幾乎可以使用Spark用於規劃Hive表上的查詢的所有元數據。

+0

謝謝!我能夠使用返回的'relation'上的'getHiveQlPartitions'獲取相關信息,並提供'partitionPruningPred'作爲參數: 'scan.findHiveTables(execPlan).flatMap(e => e.relation.getHiveQlPartitions(e。partitionPruningPred))' 這包含我需要的所有數據,包括所有輸入文件的路徑,正確分區修剪。 不幸的是,低級別的包私人訪問是必需的,標準的'inputFiles'本身並不這樣做。我認爲這是出於性能原因? – binarek