(py)spark未在配置单元视图中正确修剪分区

xkrw2x1b  于 2021-05-27  发布在  Spark
关注(0)|答案(0)|浏览(176)

我们有一个配置单元视图层供我们的分析团队使用,它为驻留在各种数据库中的数据创建一个单一的入口点。在大多数情况下,这些视图(通常是分区的)只是从基础表中选择所有列;但有时,我们会进行一些列重命名或轻行级计算(case语句、合并等,但不进行聚合)。我们发现,在具有这些行计算之一的视图中,使用pyspark读取数据时不会修剪分区。
例如,考虑下表:

create table proddb.customer_date(
customer_id string,
customer_country string
)
STORED AS PARQUET
PARTITIONED BY(partition_signup_dt string);

而这个观点

CREATE VIEW viewdb.customer_date PARTITONED ON(partition_signup_dt) AS
SELECT
  customer_id
, reflect('org.apache.commons.codec.digest.DigestUtils', 'sha256Hex', customer_id) as customer_hash
, customer_country
, partition_signup_dt
from proddb.customer_date;

如果我要执行这个:

df = spark.sql("select customer_id from viewdb.customer_date where partition_signup_dt = '2020-01-01'")

spark正确地修剪分区。现在,如果我执行这个:

df = spark.sql("select customer_hash from viewdb.customer_date where partition_signup_dt = '2020-01-01'")

spark执行全表扫描,不修剪任何分区。似乎是在应用过滤器之前计算哈希值(请注意,hive mr将按预期修剪分区)
只是为了弥补我的不足,这是预期的工作:

df = spark.sql("select reflect('org.apache.commons.codec.digest.DigestUtils', 'sha256Hex', customer_id) as customer_hash from viewdb.customer_date where partition_signup_dt = '2020-01-01'")

有人对这个问题有什么建议吗?实际上,它可能是在应用任何分区修剪之前对函数求值。不过,解释似乎没有给出任何迹象表明发生了什么。
此测试使用spark 2.4.6进行
编辑:经过进一步测试,这个问题是针对 reflect 功能。其他声明如 case 以及 coalesce 允许适当的分区修剪

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题