有效 select pyspark 中的键值镶木地板列
Efficiently select key value parquet column in pyspark
我正在处理相当大的镶木地板 table,并且 99.9% 的数据包含在单个 key:value 列中。例如:
# Cannot use hive metastore to access so we have to load this way
df = spark.read.parquet('hdfs://cluster/path/to/parquet') \
.select('id, 'version', 'details')
df.printSchema()
>> root
|-- id: string
|-- version: string
|-- details: map
| |-- key: string
| |-- value: struct
| | |-- complex_struct_1: struct
| | | |-- complex_substruct_1: struct
| | | | |-- ...
| | | |-- ...
| | |-- complex_struct_2: struct
| | | |-- complex_substruct_n: struct
| | | | |-- ...
| | | |-- ...
| | |-- complex_field_n: struct
有问题的列是 details
,可能的键是 key_1
、key_2
、两者或 none。我的问题是如何才能有效地 select 仅属于 key_1
的子字段(例如 select details['key_1'].complex_struct_1.complex_substruct_1.field
)?
因为 table 不在 hive metastore 中,我不相信我可以在这里使用 spark.sql,否则会有任何好处。我了解如何天真地加载数据库,select 整个详细信息列然后进行过滤,但考虑到详细信息列绝对庞大(数千个字段)并且我只想要一个小子集,我想利用如果可能,请在此处进行柱状访问。这是我可以更有效地做的事情,还是超出了 parquet 的能力?
您可以通过创建临时视图来使用 Spark SQL:
df.createOrReplaceTempView('df')
df2 = spark.sql("""select details['key_1'].complex_struct_1.complex_substruct_1.field from df""")
这应该是高效的,并且应该只获取您需要的结果子集。您可以执行 df2.explain()
查看查询的实际执行情况。
我正在处理相当大的镶木地板 table,并且 99.9% 的数据包含在单个 key:value 列中。例如:
# Cannot use hive metastore to access so we have to load this way
df = spark.read.parquet('hdfs://cluster/path/to/parquet') \
.select('id, 'version', 'details')
df.printSchema()
>> root
|-- id: string
|-- version: string
|-- details: map
| |-- key: string
| |-- value: struct
| | |-- complex_struct_1: struct
| | | |-- complex_substruct_1: struct
| | | | |-- ...
| | | |-- ...
| | |-- complex_struct_2: struct
| | | |-- complex_substruct_n: struct
| | | | |-- ...
| | | |-- ...
| | |-- complex_field_n: struct
有问题的列是 details
,可能的键是 key_1
、key_2
、两者或 none。我的问题是如何才能有效地 select 仅属于 key_1
的子字段(例如 select details['key_1'].complex_struct_1.complex_substruct_1.field
)?
因为 table 不在 hive metastore 中,我不相信我可以在这里使用 spark.sql,否则会有任何好处。我了解如何天真地加载数据库,select 整个详细信息列然后进行过滤,但考虑到详细信息列绝对庞大(数千个字段)并且我只想要一个小子集,我想利用如果可能,请在此处进行柱状访问。这是我可以更有效地做的事情,还是超出了 parquet 的能力?
您可以通过创建临时视图来使用 Spark SQL:
df.createOrReplaceTempView('df')
df2 = spark.sql("""select details['key_1'].complex_struct_1.complex_substruct_1.field from df""")
这应该是高效的,并且应该只获取您需要的结果子集。您可以执行 df2.explain()
查看查询的实际执行情况。