假设我从一个大表A
中选择给定的行。目标行由小索引表B
或列表C
给出。
A.join(broadcast(B), 'id').collect()
或
A.where(col('id').isin(C)).collect()
在过滤掉目标行之前,将创建一个读取 A
的所有数据的任务。以广播联接为例,在任务DAG中,我们看到Scan parquet
过程确定要读取的列,在本例中,这些列都是列。
问题是,由于A
的每一行都非常大,并且选定的行很少,所以理想情况下最好:
id
; A
列
A
输出。有可能实现这一目标吗?
顺便说一下,要输出的行可能会分散在A
中,因此无法使用分区键。
答案 0 :(得分:0)
将创建一个读取A
的所有数据的任务
你错了。虽然第一种方案在内部或左侧连接的情况下不会推送IsNotNull
join
以外的任何过滤器,但第二种方法会将In
向下推送到源。
如果isin
列表很大,则可能不需要更快,但它仍然是优化的。
如果您希望从可能的优化中充分受益,您仍应使用分段(DISTRIBUTE BY
)或分区(PARTITIONING BY
)。这些在IS IN
方案中非常有用,但在第一个方案中也可以使用分段,其中B
要广播。