菜鸡还没有找到工作(DAY41)
今日八股:
1.join属性优化
(1)map join
适合小表join大表或者小表join小表
原理:将小的那份数据给每个maptask的内存都放一份完整的数据,底层不经过shuffle,需要占用内存空间存放小的数据文件
(2)reduce join
适合大表join大表
原理:将两张表的数据在shuffle阶段利用shuffle的分组来将数据按照关键字段合并
将key相同数据放在同一个reducetask任务中
(3)bucket join
适合大表join大表
原理:将两张表按照相同的规则将数据划分,根据对应的规则进行join
2.数据倾斜
原因:数据分区规则
大多数task都结束了,只有一个task一直运行
程序出现group by count(distinct)等分组聚合场景,根据mapreduce的hash分区规则,肯定会出现数据倾斜
情况一:group by,count(distinct)
解决方案:
1.开启map端聚合
减少shuffle数据量和reduce阶段的执行时间,避免每个task数据差异过大导致数据倾斜
2.实现随机分区
select * from table distribute by rand();
3.数据倾斜时自动负载均衡
程序自动通过两个mapreduce来运行
第一个MapReduce自动进行随机分布到reducer中,每个reducer做部分聚合操作,输出结果
第二个mapreducer将上一步聚合的结果再按照业务进行处理,保证相同的分布到一起,最终聚合得到结果
情况二:join
1.提前过滤数据,是否可以mapjoin
2.bucket join将两个表数据划分为桶表,桶与桶进行Join
3.skew join专门解决数据倾斜
首先判断数据是否倾斜,如果倾斜,将倾斜数据单独使用mapjoin
其次对不倾斜的数据使用reduce join
最后将mapjoin和reducejoin结果合并
3.爆炸函数
接受map,array类型的数据作为输入,把每个元素拆开变成一行数据,输入一行输出多行
SELECTuser_id,user_name,exploded_skill -- 为炸开后的元素命名的列名
FROMuser_skills
LATERAL VIEW explode(skills) exploded_table AS exploded_skill;SELECTuser_id,user_name,skill_key,score_value
FROMuser_skills
LATERAL VIEW explode(scores) exploded_table AS skill_key, score_value;
4.增强聚合函数
SELECTcountry,province,city,SUM(amount) AS total_amount
FROM sales
GROUP BY country, province, city
GROUPING SETS ((country, province, city), -- 细粒度汇总(country, province), -- 中粒度汇总(country), -- 粗粒度汇总() -- 全局汇总
);SELECTcountry,province,city,SUM(amount) AS total_amount
FROM sales
GROUP BY ROLLUP(country, province, city);SELECTcountry,province,city,SUM(amount) AS total_amount
FROM sales
GROUP BY ROLLUP(country, province, city);
grouping sets(a,b,c) 允许你直接指定所有你感兴趣的分组组合。
rollup:它会生成所有 ROLLUP参数从左到右的所有子集组合
cube:生成所有可能的分组组合(即幂集)
5.窗口函数
函数名称(参数)over(partition by order by ROWS/RANGS)
分为3类
1.排序开窗函数
ROW_NUMBER RANK DENSE_RANK NTILE
2.分析开窗函数
FIRST LAST LEAD LAG
LAG(column, n):获取窗口内当前行之前第n行的数据。
LEAD(column, n):获取窗口内当前行之后第n行的数据。
FIRST_VALUE(column):获取窗口内第一行的数据。(到这行数据当前)
LAST_VALUE(column):获取窗口内最后一行的数据(使用时需注意窗口框架!通常结合ROWS BETWEEN)。(到这行数据当前)
3.聚合开窗函数
CONT SUM MAX MIN AVG
ROWS BETWEEN 1 PRECEDING AND CURRENT ROW:前一行 + 当前行
ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING:前3行 + 当前行 + 后1行
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW:第一行到当前行(默认带ORDER BY时)
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING:当前行到最后一行