我最近被介绍给 Spark-SQL
. 我写了一封信 Spark-SQL
运行了很长时间的查询,因此我需要对其进行调优,以将其执行时间限制在可接受的范围内。
首先,查询使用 Anti-Join
在源表和目标表之间,以便丢弃tablet中任何现有的键记录,而只考虑来自源的新键记录。只需要从src tablea中提取tablet中尚未出现的记录。
首先,我很想知道是否可以重新编写这个查询以减少执行时间。其次,如果通过加入平板电脑从源代码中获取新记录的逻辑可以以不同的方式重新编写以提高效率。
表A(来源):
id|name|Loc|cover_sk|dtid
10|John|CA|2346|3
20|Mark|MD|7459|5
30|Mike|MO|1345|6
40|Josh|CT|9898|2
平板电脑(上次运行后的当前状态)
id|name|loc|cover|day_of_week
20|Mark|MD|1234|5
40|Josh|CT|6789|6
表C:
cover_sk|cover_key|start_date
2346|EXT|2018-03-23
7459|AMB|2019-12-31
1345|DFE|2015-05-06
9898|RTE|2017-09-23
6189|EXT|2014|01-01
datedim(日期维度):
dateid|day_of_week
2|2
3|3
5|5
6|6
8|1
9|2
预期产量:
id|name|loc|cover|day_of_week
10|John|CA|1234|3
30|Mike|MO|6789|6
要求:
从src中,选择tablet中不存在的新记录。在这种情况下,ID 20和40已经存在于tablet中,因此我们从源(tablea)中拾取并继续处理剩余的记录-ID,即10和30。丢弃表A中的20和40,因为它们已经存在于平板电脑中。
使用上一步中选择的数据连接tablec以获取cover\u键。在本例中,2346和1345被选中,因为在步骤1中,我们选中了ids10和ids30,忽略了ids20和ids40,因为它已经存在于tablet中
最后加入上一步到datedim的结果集,以获取一周中的第天。
我有以下疑问:
SELECT
src.id, src.name, src.loc, c.cover_key, dt.day_of_week
FROM tableA src -- source table
LEFT ANTI JOIN tableT tgt -- Join with tableT to identify and discard existing keys
ON src.id = tgt.id
LEFT JOIN tableC c
ON src.cover_sk = c.cover_sk
INNER JOIN datedim dt
ON src.dateid = dt.dateid
表的大小如下:
tableA: 389,000,000 rec
tableT: 300,000,000 rec
tableC: 16,000 rec
datedim: 115 rec
整个查询连续运行了2个小时,我认为它有一些调整的余地。
另外,我尝试了普通的左连接而不是左反连接,来检查(平板电脑中的记录)记录是否存在,但没有成功。
感谢您的帮助。
注意:我只能访问 Spark-SQL
但不是pysparksql
谢谢
1条答案
按热度按时间kzmpq1sx1#
我建议对tablea和tableb使用id列进行重新分区,至于分区的数量,这取决于所使用的执行器/内核/内存的数量。另外,尝试广播tablec和datedim表。希望这有帮助。