Hive系列

注:大家觉得博客好的话,别忘了点赞收藏呀,本人每周都会更新关于人工智能和大数据相关的内容,内容多为原创,Python Java Scala SQL 代码,CV NLP 推荐系统等,Spark Flink Kafka Hbase Hive Flume等等~写的都是纯干货,各种顶会的论文解读,一起进步。 今天继续和大家分享一下Hive的表操作 #博学谷IT学习技术支持

文章目录

Hive系列前言一、Hive的优化1.key值问题-空KEY过滤2.空key转换3.Hive的去重问题

总结

前言

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优化操作,后续其他的优化方法会通过实战案例,继续分享

参考阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: