【问题标题】:How to list partition-pruned inputs for Hive tables?如何列出 Hive 表的分区修剪输入?
【发布时间】:2018-02-03 04:57:45
【问题描述】:

我正在使用 Spark SQL 在 Hive 中查询数据。数据已分区,Spark SQL 在查询时正确修剪分区。

但是,我需要列出给定查询的源表以及分区过滤器或特定的输入文件(.inputFiles 是一个明显的选择,但它不反映修剪)以确定哪个将进行计算的部分数据。

我最接近的方法是致电df.queryExecution.executedPlan.collectLeaves()。这包含作为HiveTableScanExec 实例的相关计划节点。但是,对于 org.apache.spark.sql.hive 包,此类是 private[hive]。我认为相关字段是relationpartitionPruningPred

有什么办法可以做到吗?

更新:感谢Jacek的建议,并在返回的relation上使用getHiveQlPartitions并提供partitionPruningPred作为参数,我能够获得相关信息:

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

这包含我需要的所有数据,包括所有输入文件的路径,正确分区修剪。

【问题讨论】:

    标签: apache-spark hive apache-spark-sql


    【解决方案1】:

    嗯,您要求的是查询执行的低级详细信息,而那里的事情却很坎坷。 您已被警告 :)

    正如你在评论中提到的,所有的执行信息都在这个private[hive] HiveTableScanExec中。

    了解HiveTableScanExec 物理运算符(即执行时的Hive 表)的一种方法是在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,我通常在spark-shell 中使用:paste -raw 来潜入这些“未知领域”。

    然后您可以简单地执行以下操作:

    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 字段是使用 Spark 分析器用于解析数据源和 Hive 表的 ResolveRelationsFindDataSourceTable 逻辑规则解析后的 H​​ive 表。

    您可以使用ExternalCatalog 接口从 Hive 元存储中获取 Spark 使用的几乎所有信息,该接口可用作spark.sharedState.externalCatalog。这为您提供了 Spark 用于计划对 Hive 表的查询的几乎所有元数据。

    【讨论】:

    • 谢谢!我能够在返回的relation 上使用getHiveQlPartitions 获取相关信息,并提供partitionPruningPred 作为参数:scan.findHiveTables(execPlan).flatMap(e =&gt; e.relation.getHiveQlPartitions(e.partitionPruningPred)) 这包含我需要的所有数据,包括所有输入文件的路径,正确分区修剪。不幸的是,这需要低级别的包私有访问,而标准inputFiles 本身并没有这样做。我认为这是出于性能原因?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 2015-09-13
    • 2018-09-07
    • 1970-01-01
    相关资源
    最近更新 更多