从spark中的镶木地板文件中读取特定列的有效方法

hor*_*01d 6 apache-spark parquet

从具有多列的拼花文件中只读取spark中的列子集的最有效方法是什么?是用spark.read.format("parquet").load(<parquet>).select(...col1, col2)最好的方法吗?我也更喜欢使用带有案例类的类型安全数据集来预先定义我的架构,但不确定.

Oli*_*Oli 11

val df = spark.read.parquet("fs://path/file.parquet").select(...)
Run Code Online (Sandbox Code Playgroud)

这只会读取相应的列.实际上,实木复合地板是一个柱状存储器,它正是这种用例的意思.尝试运行df.explain并且spark将告诉您只读取相应的列(它打印执行计划).explain如果您还使用where条件,也会告诉您哪些过滤器被推送到物理执行计划.最后使用以下代码将数据框(行的数据集)转换为案例类的数据集.

case class MyData...
val ds = df.as[MyData]
Run Code Online (Sandbox Code Playgroud)


Ale*_*rov 9

至少在某些情况下,获取包含所有列的数据框+选择子集是行不通的。例如,如果 parquet 至少包含一个 Spark 不支持类型的字段,则以下操作将会失败:

spark.read.format("parquet").load("<path_to_file>").select("col1", "col2")
Run Code Online (Sandbox Code Playgroud)

一种解决方案是提供仅包含请求的列的架构load

spark.read.format("parquet").load("<path_to_file>",
                                   schema="col1 bigint, col2 float")
Run Code Online (Sandbox Code Playgroud)

使用此功能,即使无法加载完整文件,您也可以加载 Spark 支持的 parquet 列的子集。我在这里使用 pyspark,但希望 Scala 版本有类似的东西。


hi-*_*zir 5

Spark 支持使用 Parquet 进行下推,因此

load(<parquet>).select(...col1, col2)
Run Code Online (Sandbox Code Playgroud)

很好。

我也更喜欢使用带有案例类的类型安全数据集来预定义我的架构,但不确定。

这可能是一个问题,因为在这种情况下,某些优化似乎不起作用Spark 2.0 Dataset vs DataFrame