gpt4 book ai didi

apache-spark - Spark中高效读取嵌套 Parquet 列

转载 作者:行者123 更新时间:2023-12-02 05:51:56 24 4
gpt4 key购买 nike

我有以下(简化的)架构:

root
|-- event: struct (nullable = true)
| |-- spent: struct (nullable = true)
| | |-- amount: decimal(34,3) (nullable = true)
| | |-- currency: string (nullable = true)
| |
| | ... ~ 20 other struct fields on "event" level

我正在尝试对嵌套字段求和

spark.sql("select sum(event.spent.amount) from event")

根据 Spark 指标,我正在从磁盘读取 18 GB 数据,需要 2.5 分钟。

但是,当我选择顶级字段时:

 spark.sql("select sum(amount) from event")

我在 4 秒内只读取了 2GB。

从物理计划中我可以看到,在嵌套结构的情况下,具有所有字段整个事件结构是从 Parquet 中读取的,这是一种浪费。

Parquet 格式应该能够从嵌套结构中提供所需的列,而无需读取全部内容(这是列式存储的要点)。 Spark 有什么方法可以有效地做到这一点吗?

最佳答案

解决方案:

spark.sql("set spark.sql.optimizer.nestedSchemaPruning.enabled=true")
spark.sql("select sum(amount) from (select event.spent.amount as amount from event_archive)")

查询必须以子选择方式编写。您无法将所选列包装在聚合函数中。以下查询将破坏模式修剪:

select sum(event.spent.amount) as amount from event

SPARK-4502 中涵盖了整个模式修剪工作。

肮脏的解决方法还可以在加载时指定“投影模式”:

val DecimalType = DataTypes.createDecimalType(18, 4)
val schema = StructType(StructField("event", StructType(
StructField("spent", StructType(
StructField("amount", DecimalType, true) :: Nil
), true) :: Nil
), true) :: Nil
)
val df = spark.read.format("parquet").schema(schema).load(<path>)

关于apache-spark - Spark中高效读取嵌套 Parquet 列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57331007/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com