如何让Spark只读指定的行?

时间:2018-04-05 03:47:37

标签: python apache-spark join pyspark

假设我从一个大表A中选择给定的行。目标行由小索引表B或列表C给出。

的默认行为
A.join(broadcast(B), 'id').collect()

A.where(col('id').isin(C)).collect()
在过滤掉目标行之前,

将创建一个读取 A的所有数据的任务。以广播联接为例,在任务DAG中,我们看到Scan parquet过程确定要读取的列,在本例中,这些列都是列。

Task DAG

问题是,由于A的每一行都非常大,并且选定的行很少,所以理想情况下最好:

  1. 仅读取id;
  2. A
  3. 决定使用广播连接输出的行;
  4. 根据步骤2,仅读入选定的行以从A输出。
  5. 有可能实现这一目标吗?

    顺便说一下,要输出的行可能会分散在A中,因此无法使用分区键。

1 个答案:

答案 0 :(得分:0)

  

将创建一个读取A

的所有数据的任务

你错了。虽然第一种方案在内部或左侧连接的情况下不会推送IsNotNull join以外的任何过滤器,但第二种方法会将In向下推送到源。

如果isin列表很大,则可能不需要更快,但它仍然是优化的。

如果您希望从可能的优化中充分受益,您仍应使用分段(DISTRIBUTE BY)或分区(PARTITIONING BY)。这些在IS IN方案中非常有用,但在第一个方案中也可以使用分段,其中B要广播。