替换或优化spark sql中的join



我有这样的代码

df= dataframe_input.withColumn('status_flights', F.when((F.col('WOW') == 0), 1).otherwise(0))
df = df.groupBy('Filename').agg(F.sum('status_flights').alias('status_flights'))
dataframe_input = dataframe_input.drop('status_flights').join(df, ['Filename'], 'Left')
dataframe_input = dataframe_input.filter(F.col('status_flights')>0)

这里的连接没有优化,是否有任何方法可以替换连接,因为我们正在做数据框和它自己之间的连接(在小浓缩之后)

答案在这里:

这取决于数据。更具体地说,它取决于名称列的基数。如果基数很小,则数据会不会是小的聚合和聚合后的结果可以是在join中广播。在这种情况下,连接将比窗外。另一方面,如果基数很大并且数据聚合后是大的,所以连接会被规划用吗SortMergeJoin,使用窗口会更有效率。

对于窗口,我们总共有1次洗牌+ 1次排序。在这种情况下在SortMergeJoin的左分支中我们有相同的(总shuffle +)排序)加上额外的减少洗牌和排序在右分支(by我的意思是首先汇总数据)。在右边的分支对于连接,我们还对数据进行了额外的扫描。

另外,你可以看看我在Spark峰会上分析的视频类似的例子。用户头像David Vrba

视频中回顾的是火花计划。这可以通过在您正在运行的查询上使用.explain()来完成,以查看它实际在做什么。这可能需要一些时间来学习如何阅读,但如果你想学会优化,这是很有价值的。一般来说,指导方针是,您可以做的更改越少,您的代码运行速度就越快。如果您可以将任意洗牌更改为地图边连接,您将运行得更快。(这高度依赖于您的数据适合内存)

在上面的文章中没有讨论的一件事是,如果您将定期运行此报告,那么它们可能在实现您正在做的组以使其运行得更快方面具有价值。这需要在插入上做额外的工作,但将帮助您从表中获得所有性能。一般来说,您可以将更多的数据预先分解成有用的报告格式,您的查询运行得越快。

最新更新