Dataframe 将数据框转换为数据集后的选择是否优化?

Dataframe 将数据框转换为数据集后的选择是否优化?,dataframe,apache-spark,apache-spark-sql,parquet,catalyst-optimizer,Dataframe,Apache Spark,Apache Spark Sql,Parquet,Catalyst Optimizer,我有以下情况: case class A(name:String,age:Int) val df = List(A("s",2)).toDF df.write.parquet("filePath") val result = spark.read.parquet("filePath").as[A].select("age") 以上是否已优化为仅选择年龄?在看到结果后,解释我看到了以下内容 'Project [unresolvedalias('age, None)] +- Relatio

我有以下情况:

 case class A(name:String,age:Int)
 val df = List(A("s",2)).toDF
 df.write.parquet("filePath")
 val result = spark.read.parquet("filePath").as[A].select("age")
以上是否已优化为仅选择年龄?在看到结果后,解释我看到了以下内容

'Project [unresolvedalias('age, None)]
+- Relation[name#48,age#49] parquet

== Analyzed Logical Plan ==
age: int
Project [age#49]
+- Relation[name#48,age#49] parquet

== Optimized Logical Plan ==
Project [age#49]
+- Relation[name#48,age#49] parquet

== Physical Plan ==
*(1) FileScan parquet [age#49] Batched: true, Format: Parquet, Location:    InMemoryFileIndex[file:/Volumes/Unix/workplace/Reconciliation/src/TFSReconciliationCore/~/Downloa..., PartitionFilters: [], PushedFilters: [], ReadSchema: struct<age:int>

似乎只有年龄是可以阅读的。但这样做的目的是什么呢?我读物理计划正确吗?

是的,你读得对。拼花地板文件有两列-名称和年龄:

但事实上,只有年龄才会被解读:

 Project [age#49]
但这样做的目的是什么呢

对于上面的优化,Spark需要创建一个内部模式

在某些情况下,如拼花文件,我们有一个包含元数据和模式的页脚,尽管默认情况下Spark必须读取所有页脚才能合并(可能)不同的模式。 在其他csv、json等中,如果用户不提供模式,Spark需要扫描数据并创建它

我们还需要一些通用的容器,它可以让我们访问这些值,我们有一个称为Row的容器

是具有有序字段集合的通用行对象 可通过顺序/索引访问的,也称为通用访问 序数,一个名称,也称为本机原语访问或使用Scala的 模式匹配

在您的示例中,完全可以编写以下代码:

spark.read.parquet("filePath").select("age")
Read方法返回Dataframe,实际上它只是一个。 当我们使用as时,我们正在将数据集[Row]转换为数据集[A],其中A几乎可以是任何case类

在我看来,它使代码更干净,可读性更强。在使用类似SQL的方法时,这没有多大区别,但是当我们需要在混合中添加map/flatMap或自定义聚合时,代码将变得更容易理解

spark.read.parquet("filePath").select("age")