spark执行map-join优化

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

内容简介:我在执行以下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的执行计划,然后再进行优化。


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

查看所有标签

猜你喜欢:

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

创业在路上

创业在路上

罗永浩 / 中信出版集团 / 2018-9 / 58.00 元

★ 罗永浩的人生经历就是一本典型的创业宝典,对于如今的年轻人,具有可借鉴的实用价值。 ★ 还原了真实的、区别于公众形象的罗永浩。 ★ 送给创业者满满的干货: 比如“并不是所有人都适合创业。”“管控公司zui重要的三件事:找钱、找人和定战略方向。”“不要试图去补短板,一定不要自己去补自己不擅长的”等 ★ 《创业在路上》集结了2017年超长对话栏目《长谈》、罗永浩的创业分享课的......一起来看看 《创业在路上》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具