SparkSQL之SQL优化
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语句优化方式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分配到⼀个分区⾥,造成了’⼀个⼈累死,其他⼈闲死’的情况,
这种情况是我们不能接受的,这也违背了并⾏计算的初衷,⾸先⼀个节点要承受着巨⼤的压⼒,⽽其他节点计算完毕后要⼀直等待这个忙碌的节点,也拖累了整体的计算时间,可以说效率是⼗分低下的.
判断数据倾斜的⽅法:
任务中单个或者少量的task拖慢整个任务速度。
通过查看id的分布,返回表A的id分布情况,通过返回结果可以看出是否某些id的数量远⼤于其他。
select id,count(id)as id_nums group by id order by num desc
处理数据倾斜的⽅法
1、过滤或者去重:如果导致倾斜的id 在最后的结果没有作⽤,可以在Join 之前将其过滤掉。例如,id=NULL 的数据往往是多余
的。
2、Map Join:如果join的表不⼤,使⽤Map Join。
3、数据分离:可以将表A 的数据分为两部分A1和A2,A1中不包含数据倾斜的数据(id=b),A2中只包
含数据倾斜的数据(id=a)。A1
和A2 分别与B 进⾏Join,然后将结果Union。SQL 如下所⽰。A1与A2 的Join 没有数据倾斜的问题。由于A2通常不会很⼤,A2与B的Join 采⽤Map Join。但是如果A2很⼤则不适⽤
4、数据打散:将有数据倾斜的表(A)中的id加上后缀,起到“打散”的作⽤,即"id_0"-“id_2”。为了结果正确性,⼩表B中的id需
要将每条数据都“复制”多份。如下图所⽰。
数据分离:
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()*10000as 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没有重复

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。