从 Spark 中的 parquet 文件读取特定列的有效方法

问题描述 投票:0回答:4

从具有许多列的 parquet 文件中仅读取 Spark 中列的子集的最有效方法是什么?使用

spark.read.format("parquet").load(<parquet>).select(...col1, col2)
是最好的方法吗?我还更喜欢使用带有案例类的类型安全数据集来预定义我的架构,但不确定。

apache-spark parquet
4个回答
34
投票
val df = spark.read.parquet("fs://path/file.parquet").select(...)

这只会读取相应的列。事实上,Parquet 是一种柱状存储,它正是针对这种类型的用例。尝试运行

df.explain
,spark 会告诉您仅读取相应的列(它会打印执行计划)。如果您还使用 where 条件,
explain
还会告诉您哪些过滤器被推送到物理执行计划。最后使用以下代码将数据帧(行数据集)转换为案例类的数据集。

case class MyData...
val ds = df.as[MyData]

9
投票

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

spark.read.format("parquet").load("<path_to_file>").select("col1", "col2")

一种解决方案是向

load
提供仅包含请求列的架构:

spark.read.format("parquet").load("<path_to_file>",
                                   schema="col1 bigint, col2 float")

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


7
投票

Spark 支持 Parquet 下推,因此

load(<parquet>).select(...col1, col2)

还好。

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

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


3
投票

Parquet 是一种柱状文件格式。它正是为此类用例而设计的。

val df = spark.read.parquet("<PATH_TO_FILE>").select("column1", "column2", ...)

应该为你完成这项工作。

© www.soinside.com 2019 - 2024. All rights reserved.