Hive系列
注:大家觉得博客好的话,别忘了点赞收藏呀,本人每周都会更新关于人工智能和大数据相关的内容,内容多为原创,Python Java Scala SQL 代码,CV NLP 推荐系统等,Spark Flink Kafka Hbase Hive Flume等等~写的都是纯干货,各种顶会的论文解读,一起进步。
今天继续和大家分享一下Hive的表操作
#博学谷IT学习技术支持
前言
1、Hive是数仓管理工具,用来管理数仓
2、Hive可以将数仓存在HDFS上的文件变成一张张的表
3、Hive提供一种HiveSQL可以表进行分析处理
4、HiveSQL底层默认是MapReduce,以后可以换成其他的引擎(Spark),我们写HiveSQL会去匹配底层的MR模板,匹配上则执行,否则不能执行
一、Hive的优化
1.key值问题-空KEY过滤
有时join超时是因为某些key对应的数据太多,而相同key对应的数据都会发送到相同的reducer上,从而导致内存不够。此时我们应该仔细分析这些异常的key,很多情况下,这些key对应的数据是异常数据,我们需要在SQL语句中进行过滤。例如key对应的字段为空,操作如下:
环境准备:
-- 普通查询
select * from 表A a left join 表B b on a.id = b.id where 过滤a表和b表的最新数据
-- 高效率查询-谓词下推
select * from 表A a where 过滤a表的最新数据
select * from 表B b where 过滤b表的最新数据
select * from (select * from 表A a where 过滤a表的最新数据) a left join (select * from 表B b where 过滤b表的最新数据) b on a.id = b.id
2.空key转换
有时虽然某个key为空对应的数据很多,但是相应的数据不是异常数据,必须要包含在join的结果中,此时我们可以表a中key为空的字段赋一个随机的值,使得数据随机均匀地分不到不同的reducer上。例如:
-- 不随机分布:
set hive.exec.reducers.bytes.per.reducer=32123456;
set mapreduce.job.reduces=7;
INSERT OVERWRITE TABLE jointable
SELECT a.*
FROM nullidtable a
LEFT JOIN ori b ON CASE WHEN a.id IS NULL THEN 'hive' ELSE a.id END = b.id;
No rows affected (41.668 seconds) 52.477
结果:这样的后果就是所有为null值的id全部都变成了相同的字符串,及其容易造成数据的倾斜(所有的key相同,相同key的数据会到同一个reduce当中去)
为了解决这种情况,我们可以通过hive的rand函数,随记的给每一个为空的id赋上一个随机值,这样就不会造成数据倾斜
-- 随机分布:
set hive.exec.reducers.bytes.per.reducer=32123456;
set mapreduce.job.reduces=7;
INSERT OVERWRITE TABLE jointable
SELECT a.*
FROM nullidtable a
LEFT JOIN ori b ON CASE WHEN a.id IS NULL THEN concat('hive', rand()) ELSE a.id END = b.id;
No rows affected (42.594 seconds)
3.Hive的去重问题
-- 准备数据
1 2022-01-01 zhangsan 80
1 2022-01-01 zhangsan 80
1 2022-01-01 zhangsan 80
2 2022-01-01 lisi 70
2 2022-01-01 lisi 70
2 2022-01-01 lisi 70
------------去重--------------
1 2022-01-01 zhangsan 80
2 2022-01-01 lisi 70
方法1:distinct
select distinct * from 表
注意,在Hive中distinct必须只有一个reduce才能完成整体的去重,效率极低,千万不要用
方法2:group by
select sid,sname,sbirth,ssex from student2 group by sid,sname,sbirth,ssex;
方法3:row_number() over()
with t as (
select
*,
row_number() over (partition by sid ) rk
from student2
)
select * from t where rk = 1;
注意,生产环境就用该方式进行去重,这里不能使用rank和dense_rank()
总结
今天继续和大家分享一下Hive的表操作8,一些简单基础的Hive优化操作,后续其他的优化方法会通过实战案例,继续分享