Spark SQL:空 table 加入大 table 慢
Spark SQL: Empty table join with large table slow
我有2个table
- 交易table(按年份划分)
- 元数据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
}
我有2个table
- 交易table(按年份划分)
- 元数据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
}