我在 spark 查询中有一组窗口函数,其中包括 user_num 上的分区。其中一个 user_nums 的行比其他的多得多。这一行是在单个任务中计算的,它具有更高的随机读取、随机远程读取并最终需要大量时间。
Select LAG(e) OVER (PARTITION BY user_num, a, date ORDER BY time) as aa,
FIRST_VALUE(e) OVER (PARTITION BY a, date ORDER BY time ROWS
BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) as bbb
FROM table
是否有任何设置或任何方法可以在不同的任务上运行此程序,或者以不需要或最少更改窗口函数逻辑的方式缩短此时间?
I.E 我可以在某个点缓存,增加分区数,增加 exec mem 等
答案 0 :(得分:0)
关于通过牺牲一些数据损失来扩大规模的建议,即增加分区窗口的粒度。
示例:
现在,您的单个任务将分为 24 个任务。
但这会为您的 LAG 带来更多 NULLS。例如,如果您正在计算偏移量为 4 的滞后,那么对于每一小时的数据,您将有 3 个 NULL 值。
所以,这就像速度与准确数据之间的权衡。
您可以进一步将粒度增加到分钟,以实现更多的并行性,但代价是更多的 NULL。
在损失方面的进一步改进:
如果您选择使用较低的粒度,这可能会影响其他“user_nums”。 最好分成 2 个 dfs :
result = result_from_Skew.union(result_from_normal)
答案 1 :(得分:0)
我在这里做了两件事:
FIRST_VALUE(e) OVER (PARTITION BY a, date ORDER BY time desc ROWS 无界前行和当前行之间) as bbb