【问题标题】:Efficient way to read specific columns from parquet file in spark从火花中的镶木地板文件中读取特定列的有效方法
【发布时间】:2018-07-03 11:28:27
【问题描述】:

从具有许多列的镶木地板文件中仅读取 spark 中的一部分列的最有效方法是什么?使用spark.read.format("parquet").load(<parquet>).select(...col1, col2) 是最好的方法吗?我也更喜欢使用带有案例类的类型安全数据集来预定义我的模式,但不确定。

【问题讨论】:

    标签: apache-spark parquet


    【解决方案1】:
    val df = spark.read.parquet("fs://path/file.parquet").select(...)
    

    这只会读取相应的列。事实上,parquet 是一种列式存储,它正好适用于这种类型的用例。尝试运行df.explain,spark 会告诉您只读取了相应的列(它会打印执行计划)。 explain 还会告诉您哪些过滤器被推送到物理执行计划,以防您还使用 where 条件。最后使用以下代码将数据框(行数据集)转换为案例类的数据集。

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

    【讨论】:

    • 什么是'...'?
    • 这意味着您可以定义适合您数据的案例类。例如case class MyData(col1: Int, col2: String)
    • select(col1,col2,...) 其中 col1 和 col2 是表示列名的字符串
    【解决方案2】:

    Spark 支持 Parquet 下推,所以

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

    没问题。

    我还希望使用带有案例类的类型安全数据集来预定义我的架构,但不确定。

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

    【讨论】:

    • 什么是'...'?
    【解决方案3】:

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

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

    应该为你做这项工作。

    【讨论】:

    • 什么是'...'?
    【解决方案4】:

    至少在某些情况下,获取包含所有列的数据框 + 选择子集是行不通的。例如。如果 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 支持的 parquet 列的子集。我在这里使用 pyspark,但希望 Scala 版本有类似的东西。

    【讨论】:

    • 填写 "col1", "col2" 而不是 ... 使这个答案比我目前接受的答案稍微有用/实用。
    猜你喜欢
    • 2019-02-19
    • 1970-01-01
    • 2018-12-20
    • 2016-01-18
    • 1970-01-01
    • 2021-09-05
    • 2017-03-17
    • 1970-01-01
    相关资源
    最近更新 更多