Spark SQL:空 table 加入大 table 慢

Spark SQL: Empty table join with large table slow

我有2个table

  1. 交易table(按年份划分)
  2. 元数据table(所有键唯一无分区,30M记录) 我的火花 SQL 是
SELECT * FROM Transaction WHERE PARTITION_YEAR = 2022; (result: 0 record)

出结果非常快

SELECT * FROM Metadata WHERE KEY = "A" (result: 1 record)

2-3 秒得到结果

最后

SELECT * FROM Transaction t LEFT JOIN Metadata m ON t.key = m.key WHERE t.PARTITION_YEAR = 2022;

相当慢(3 分钟)

虽然

SELECT * FROM (SELECT * FROM Transaction WHERE PARTITION_YEAR = 2022) t LEFT JOIN Metadata m ON t.key = m.key;

还需等待(3 分钟)

根据您的查询行为,我猜您的文件格式是 parquet.

SELECT * FROM Metadata WHERE KEY = "A" 

这就像一个支持 PUSHDOWN 过滤器的过滤器操作,它不会扫描整个 table ,而是快速查看您感兴趣的列 (KEY) 的 parquet 元数据 (RANGE) 并找出。

但是当你加入 Spark 时: 它必须将 整个 table 的 METADATA 引入内存 ,并且它必须根据您的连接条件扫描和打乱数据。即,联接不支持 PUSHDOWN 过滤器。


您最后的 2 个查询基本相同。 Spark只会将2022个数据带入内存。即使您的分区可能是空的,也会加载 30M 的 METADATA 记录。


如果你想避免空分区的这种情况,你应该检查分区是否为空然后只触发

cheapest/efficient检查方法:

val dfPartition = spark.sql("SELECT * FROM Transaction WHERE PARTITION_YEAR = 2022;")

if(!dfPartition.isEmpty()) // fastest. 
{
  //Fire your join query
}