我有两个表
- 事务表(按年份划分(
- 元数据表(所有键都是唯一的,没有分区,30M条记录(我的Spark SQL是
SELECT * FROM Transaction WHERE PARTITION_YEAR = 2022; (result: 0 record)
快速获得结果
从元数据中选择*WHERE KEY="A";(结果:1条记录(
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分钟(
根据您的查询行为,我猜您的文件格式是镶木地板。
SELECT * FROM Metadata WHERE KEY = "A"
这就像一个支持PUSHDOWN过滤器的过滤器操作,它不会扫描整个表,而是快速查看您感兴趣的列(KEY(的镶木地板元数据(RANGE(并找出答案。
但当你加入Spark时:它必须将METADATA的整表放入内存,并且必须根据您的联接条件扫描和混洗数据。即PUSHDOWN过滤器不支持联接。
您的最后两个查询基本相同。Spark只会将2022个数据带入内存。即使您的分区可能是空的,也会加载3000万条METADATA记录。
如果你想避免空分区出现这种情况,你应该检查分区是否为空,然后只启动
最便宜/有效的检查方式:
val dfPartition = spark.sql("SELECT * FROM Transaction WHERE PARTITION_YEAR = 2022;")
if(!dfPartition.isEmpty()) // fastest.
{
//Fire your join query
}