从Spark中读取Hive表作为数据集

时间:2018-04-09 19:41:59

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

我正在尝试将spark中的hive表作为强类型Dataset读取,并且我注意到分区没有被修剪而不是在同一hive表的数据帧上执行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")

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

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

正确修剪分区。有人可以解释为什么在将表映射到案例类时会丢失分区信息吗?

1 个答案:

答案 0 :(得分:3)

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

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

第二种情况不应该编译(没有groupByKey变体需要字符串),所以不可能告诉,但一般来说它也不应该修剪,除非你的意思:

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

另见我对Spark 2.0 Dataset vs DataFrame的回答。