Spark SQL 优化笔记

前言

记录自己在工作开发中遇到的SQL优化问题

1、避免用in 和 not in

解决方案:

  • 用exists 和 not exists代替
  • 用join代替

not exists示例

not in:

select stepId,province_code,polyline from route_step where stepId not in (select stepId from stepIds)

not exists:

select stepId,province_code,polyline from route_step where road!='解析异常' and  not exists (select stepId from stepIds where route_step.stepId = stepIds.stepId)

自己遇到的问题

上面not in会抛出异常

18/12/26 11:20:26 WARN TaskSetManager: Stage 3 contains a task of very large size (17358 KB). The maximum recommended task size is 100 KB.
Exception in thread "dispatcher-event-loop-11" java.lang.OutOfMemoryError: Java heap space

首先会导致某个task数量很大,且总task数量很少(task数目不等于rdd或df的分区数,目前不知道原因),接着报java.lang.OutOfMemoryError,试了很多方法,最后用not exists,没有上面的异常

效率

not in慢的原因是 not in不走索引

疑问:not in是非相关子查询,not exists是相关子查询,而从理论上来说非相关子查询比相关子查询效率高(看下面的参考),但是这里却相反,矛盾,不知道为啥~

参考博客:

2、in 会导致数据倾斜

longitudeAndLatitudes和lineIds都有160个分区,且数据平衡(每个分区的数目差不多),但是下面的语句则有问题

select * from longitudeAndLatitudes where lineId  in (select lineId from lineIds)

虽然分区数还是160,但是只有两三个分区有数,其他分区的数量都为0,这样就导致数据倾斜,程序执行很慢,如果非要用in的话,那么需要repartition一下

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券