0
点赞
收藏
分享

微信扫一扫

Spark SQL之SQL优化

像小强一样活着 2022-02-22 阅读 241

Spark SQL之SQL优化

主要关注于执行性能问题

1、避免使用不必要的UDF函数

UDF:用户定义函数,可以直接在SQL语句中计算的函数,如:count、sum、avg、max、min等

2、没有指定数据分区

SQL-1: SELECT date FROM test_table WHERE date = '20170829' and value = 1;
SQL-2: SELECT date FROM test_table PARTITION(p_20170829) p WHERE value = 1

SQL-1虽然通过where表达式能够筛选到并执行所需的分区,但是在分析的时候会先获取所有的分区列表再进行筛选,会导致更多的内存占用,显然SQL-2更优

3、避免使用笛卡尔积

简单了解什么是sql里的笛卡尔积

SQL-1: select * from gbk, utf8 where gbk.key= utf8.key
SQL-2: select * from gbk join utf8 where gbk.key= utf8.key

上面是先对tabel进行笛卡尔积再where筛选,应当按如下方式书写

select * from gbk join utf8 on gbk.key= utf8.key

4、show Rowcount

读取一个表有多少行记录,虽然count也可以,但是速度非常慢!

show rowcount extended test;

按分区来显示每个分区有多少行记录

5、show Tablesize

读取一个表有多大,单位是字节

show tablesize extended test;

6、避免使用delete和update

7、当存在小表join的时候,查看是否可以使用mapjoin

MAPJION会把小表全部读入内存中,在map阶段直接拿另外一个表的数据和内存中表数据做匹配,由于在map是进行了join操作,省去了reduce运行的效率也会高很多。
简单说就是在Map阶段将小表读入内存,顺序扫描大表完成Join。这样就不会由于数据倾斜导致某个reduce上落数据太多而失败。

8、数据倾斜

Join的时候,相同的key会hash到同一task中进行。如果某个key值太多,这个task就会成为瓶颈。

简单来说就是大量的相同key被partition分配到一个分区里,造成了’一个人累死,其他人闲死’的情况,这种情况是我们不能接受的,这也违背了并行计算的初衷,首先一个节点要承受着巨大的压力,而其他节点计算完毕后要一直等待这个忙碌的节点,也拖累了整体的计算时间,可以说效率是十分低下的.

判断数据倾斜的方法:

select id,count(id) as id_nums group by id order by num desc

处理数据倾斜的方法

数据分离:

select * from (
select * from A1 join B on A1.id = B.id
union all
select /*+ MAPJOIN (A2) */ * from A2 join B on A2.id = B.id
)

数据打散:
处理之前需要先查看一下id的分布情况

表A:
SELECT id, value, concat(id, string1(cast(rand() * 10000 as int)%3)) as new_id 
FROM A;
表B:
SELECT id, value, concat(id, suffix) as new_id
FROM (
   SELECT id, value, suffix
   FROM B Lateral View explode(array(0,1,2)) tmp as suffix
)

9、join与groupby的顺序

如果Join 后有聚合函数操作,尽可能把聚合操作放到Join 之前,这样在Join 时 key 是单一的,避免数据倾斜。例如,

select t1.key, t1.total from
(select key ,sum(value) as total from t1 group by key
) t1
join t2 on t1.key = t2.key

前提是t2的key没有重复

举报

相关推荐

0 条评论