我们有一个配置单元视图层供我们的分析团队使用,它为驻留在各种数据库中的数据创建一个单一的入口点。在大多数情况下,这些视图(通常是分区的)只是从基础表中选择所有列;但有时,我们会进行一些列重命名或轻行级计算(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
允许适当的分区修剪
暂无答案!
目前还没有任何答案,快来回答吧!