spark执行map-join优化

栏目: 编程工具 · 发布时间: 6年前

内容简介:我在执行以下sql语句的时候遇到了执行内存不够的问题,原先我还以为是内存不够,然后加大了内存,但是还是执行失败。后面我在spark ui中看到了该sql的执行计划,该sql语句执行了Map-side Join操作,但是spark把a表当成了小表,准备把a表broadcast到其他的节点,然后就是一直卡在这步broadcast操作上。 造成上述问题的原因就是spark认为a表是一个小表,但是在spark ui上明显可以看到a表读了很多的行。但是为什么spark还会认为a表是一个小表呢?原因是spark判断一个

我在执行以下 sql 语句的时候遇到了执行内存不够的问题,原先我还以为是内存不够,然后加大了内存,但是还是执行失败。

// a是一个几亿行的大表,b是一个只有几十行的小表。a和b都是由hive创建的表
select * from a where id not in (select id from b)

后面我在spark ui中看到了该sql的执行计划,该sql语句执行了Map-side Join操作,但是spark把a表当成了小表,准备把a表broadcast到其他的节点,然后就是一直卡在这步broadcast操作上。 造成上述问题的原因就是spark认为a表是一个小表,但是在spark ui上明显可以看到a表读了很多的行。但是为什么spark还会认为a表是一个小表呢?原因是spark判断一个hive表的大小会用hive的metastore数据来判断,因为我们的a表没有执行过ANALYZE TABLE,自然a表的metastore里面的数据就不准确了。

解决方法?

既然知道了问题,要解决就很简单了。有如下几个解决方法:

设置spark.sql.statistics.fallBackToHdfs=True

该参数能让spark直接读取hdfs的文件大小来判断一个表达大小,从而代替从metastore里面的获取的关于表的信息。这样spark自然能正确的判断出表的大小,从而使用b表来进行broadcast。

使用hint

在使用sql语句执行的时候在sql语句里面加上mapjoin的注释,也能够达到相应的效果,比如把上述的sql语句改成:

select /*+ BROADCAST (b) */ * from a where id not in (select id from b)

这样spark也会使用b表来进行broadcast。

使用spark代码的方式

使用broadcast函数就能达到此效果:

from pyspark.sql.functions import broadcast
broadcast(spark.table("b")).join(spark.table("a"), "id").show()

拓展知识

什么时候spark才会使用Map-side Join?

只有当要进行join的表的大小小于spark.sql.autoBroadcastJoinThreshold(默认是10M)的时候,才会进行mapjoin。

总结

上述的优化同样也适用于其他的计算引擎,比如Impala通过hint和执行表的位置调整也能够优化join操作,通过explain也可以查看sql的执行计划,然后再进行优化。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

终极算法

终极算法

[美] 佩德罗·多明戈斯 / 黄芳萍 / 中信出版集团 / 2017-1-1 / 68.00元

算法已在多大程度上影响我们的生活? 购物网站用算法来为你推荐商品,点评网站用算法来帮你选择餐馆,GPS系统用算法来帮你选择最佳路线,公司用算法来选择求职者…… 当机器最终学会如何学习时,将会发生什么? 不同于传统算法,现在悄然主导我们生活的是“能够学习的机器”,它们通过学习我们琐碎的数据,来执行任务;它们甚至在我们还没提出要求,就能完成我们想做的事。 什么是终极算法? ......一起来看看 《终极算法》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

MD5 加密
MD5 加密

MD5 加密工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试