比如获取每个员工最高薪水记录
方案一:
selecet *
from a
inner join(select user_id,max(salary) as max_salary from a group by user_id) b
on a.user_id = b.user_id and a.salary = b.max_salary
方案二:减少了join *** 作,性能提升
select *
from
(select *,row_number()over(partition by user_id order by salary desc) as rank_salary from a ) as a
where a.rank_salary = 1
二、distinct聚合优化
方法一:只有一个reduce处理全量数据,并发度不够,存在单点瓶颈
SELECT COUNT(DISTINCT userid) FROM emp ;
方法二:reduce就会有多个,性能提升很多
SELECT COUNT(userid) FROM (SELECT distinct userid FROM emp) as sub;
方法三:reduce就会有多个,性能提升很多
SELECT COUNT(*) from (SELECT userid FROM emp group by userid ) as sub
三、使用with as 代替子查询
with sub as
(SELECT userid FROM emp group by userid)
select count(*) from sub;
四、聚合技巧-使用窗口函数grouping sets、with cube
例如:分别按照性别、年龄、部门查询人数,要分别写三次SQL,执行三次
优化方法:可用grouping sets接在group by后,括号里写出组合的维度,用逗号隔开
select sex,age,dept,count(user_id)
from a
group by sex,age,dept
grouping sets (sex,age,dept);
-- 若还想查看部门的性别分布
select sex,age,dept,count(user_id)
from a
group by sex,age,dept
grouping sets (sex,age,dept,(dept,sex));
with cube:根据group by 维度的所有组合进行聚合
-- 维度:性别、年龄、部门、性别+年龄、性别+部门、年龄+部门、性别+年龄+部门
select sex,age,dept,count(user_id)
from a
group by sex,age,dept
with cube;
五、join连接优化
1、小表在前,大表在后。
2、使用相同的连接键(只产生一个MapReduce job)。
3、尽早过滤数据。 减少每个阶段的数据量,对于分区表要加分区,同时只选择需要使用到的字段。逻辑过于复杂时引入中间表。
六、解决数据倾斜1、数据倾斜的表现
任务进度⻓时间维持在99%(或100%),查看任务监控⻚面,发现只有少量(1个或几个)reduce子任务未完成。因为其处理的数据量和其他reduce差异过大。 2、数据倾斜原因与方法
1)空值产生的数据倾斜
方法:表连接时若连接条件里有很多空值,建议在连接条件中增加过滤。
-- 例如:
select * from a inner join b on a.id = b.id and a.id is not null and b.id is not null
2)大小表连接(其中一张表很大,另一张很小)
方法:将小表放在内存里,在map端做join(表小放在左侧)
3)两张表连接条件的字段数据类型不一致
方法:将连接条件的字段类型转换成一致的
附思维导图:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)