【问题标题】:Reading Hive table from Spark as a Dataset从 Spark 读取 Hive 表作为数据集
【发布时间】:2018-04-09 19:41:59
【问题描述】:

我正在尝试将 spark 中的配置单元表读取为强类型 Dataset,并且我注意到分区没有被修剪,而不是对来自同一个配置单元表的数据帧执行 Spark SQL。

case class States(state: String, country: String)
val hiveDS = spark.table("db1.states").as[States]
//no partition pruning
hiveDS.groupByKey(x=>x.country).count().filter(x=>x._1 == "US")

states 是按国家/地区划分的,因此当我对上述数据集进行计数时,查询会扫描所有分区。但是,如果我这样阅读 -

val hiveDF = spark.table("db1.states")
//correct partition pruning
hiveDF.groupByKey("country").count().filter(x=>x._1 == "US")

分区被正确修剪。谁能解释为什么将表映射到案例类时会丢失分区信息?

【问题讨论】:

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


    【解决方案1】:

    TL;DR在第一种情况下缺少分区修剪是预期的行为。

    这是因为从优化器的角度来看,与 DataFrame DSL / SQL 使用的操作不同,对对象的任何操作都是一个黑盒子。为了能够优化像 x=> x._1 == "US"x => x.country 这样的功能,Spark 必须应用复杂且不可靠的静态分析,而这样的功能既不存在也不(据我所知)未来计划。

    第二种情况不应该编译(没有groupByKey 变体接受字符串),所以无法判断,但一般也不应该修剪,除非你的意思是:

    hiveDF.groupBy($"country").count().filter($"country" =!= "US")
    

    另请参阅我对Spark 2.0 Dataset vs DataFrame 的回复。

    【讨论】:

    • 谢谢!,我希望如此,但找不到此行为的正确文档。感谢您确认我的假设
    猜你喜欢
    • 2022-01-02
    • 2018-03-23
    • 2019-07-09
    • 1970-01-01
    • 2017-09-03
    • 2023-03-31
    • 2020-06-28
    • 1970-01-01
    • 2020-12-30
    相关资源
    最近更新 更多