数仓写多最多的就是sql,作为一个资深的sql工程师,sql性能是很重要的。以我个人经验来说有几个影响sql性能的问题
- 动态谓词下推
- 动态join策略选择
- 动态并行度
hive或者是其他的,都是利用静态的tableA和tableB的统计数据(数据量),生成执行计划,然后直接执行
这将出现一些问题。
比如:
- 并行度可能出现问题.
按照执行计划给定的并行度(比较粗犷,比如200),这会导致两个极端,我的sql经过过滤之后,一共就1条数据,然后还傻乎乎的去启动200个任务,另外一个极端就是处理20亿数据,一共就给200个task。这种并行度就不太合适,需要一个动态调整的并行度的工具,在spark3.0出现了这个工具,叫做aqe,具体可以大家去官网看看。还有另外一种就是手工指定,也叫作Partitioning Hints - join策略也可能出现问题
熟悉spark sql的话,了解spark的4中join策略,分别为broadcast,shuffle hash,merge sort,SHUFFLE_REPLICATE_NL
因为静态生成的执行计划,是比较死板的,无法确定后续经过筛选之后数据量有多少,所以执行的策略可能就不太合适,比如还是上面那个例子,筛选之后就只剩你下1条,但是老版本的spark sql还是会傻乎乎的走性能最差的merge sort ,而不是走性能更好的broadcast或者是shuffle hash,如果大家对shuffle hash想了解,请查看我另外一篇博客 - 动态谓词下推
这个我也是很明白,大致是能解决下面这个问题
但是我在hive上确实碰到过,下推不成功的例子,如下
select * from tableA a left join Tableb b on a.id=b.id
where a.part_dt=‘2021-10-10’ and b.part_dt=‘2021-10-10’ and a.status=‘2’
通过查看日志中处理的数据量以及explain,确定执行计划是先join,后做part_dt筛选
这个性能不忍直视,30亿的表,存一个月就接近1000亿了
这些基本上都是spark官网的内容,经过我的一些理解,也许有问题,请见谅
特性基本上都是3.0的版本引入的,请各位注意



