Q1、 udf,udaf,udtf的区别?
Hive中有三种UDF:
1、用户定义函数(user-defined function)UDF;
2、用户定义聚集函数(user-defined aggregate function,UDAF);
3、用户定义表生成函数(user-defined table-generating function,UDTF)。
UDF操作作用于单个数据行,并且产生一个数据行作为输出。大多数函数都属于这一类(比如数学函数和字符串函数)。
UDAF 接受多个输入数据行,并产生一个输出数据行。像COUNT和MAX这样的函数就是聚集函数。
UDTF 操作作用于单个数据行,并且产生多个数据行-------一个表作为输出。
简单来说:
UDF:返回对应值,一对一 | UDAF:返回聚类值,多对一 | UDTF:返回拆分值,一对多
Q2、 请写出你在工作中自定义过的udf函数,简述定义步骤
步骤:
1.extends UDF,实现evaluate()
2.add JAR /home/hadoop/hivejar/udf.jar;
3.create temporary function tolowercase as ‘com.ghgj.hive.udf.ToLowerCase’;
4.使用
5.drop temporary function tolowercase;
Q3、 Hive 内部表和外部表的区别?
创建外部表多了external关键字说明以及location path.
Hive中表与外部表的区别:
1、在导入数据到外部表,数据并没有移动到自己的数据仓库目录下,也就是说外部表中的数据并不是由它自己来管理的!而表则不一样;
2、在删除表的时候,Hive将会把属于表的元数据和数据全部删掉;而删除外部表的时候,Hive仅仅删除外部表的元数据,数据是不会删除的!
Q4、 Hive 分区表与分桶表区别
分区在HDFS上的表现形式是一个目录, 分桶是一个单独的文件
分区: 细化数据管理,直接读对应目录,缩小mapreduce程序要扫描的数据量
分桶: 1、提高join查询的效率(用分桶字段做连接字段)
2、提高采样的效率
Q5、 cluster by,order by,sort by distribute by的使用场景
order by:会对输入做全局排序,因此只有一个Reducer(多个Reducer无法保证全局有序),然而只有一个Reducer,会导致当输入规模较大时,消耗较长的计算时间。
sort by:不是全局排序,其在数据进入reducer前完成排序,因此,如果用sort by进行排序,并且设置mapred.reduce.tasks>1,则sort by只会保证每个reducer的输出有序,并不保证全局有序。sort by不同于order by,它不受hive.mapred.mode属性的影响,sort by的数据只能保证在同一个reduce中的数据可以按指定字段排序。使用sort by你可以指定执行的reduce个数(通过set mapred.reduce.tasks=n来指定),对输出的数据再执行归并排序,即可得到全部结果。
distribute by:是控制在map端如何拆分数据给reduce端的。hive会根据distribute by后面列,对应reduce的个数进行分发,默认是采用hash算法。sort by为每个reduce产生一个排序文件。在有些情况下,你需要控制某个特定行应该到哪个reducer,这通常是为了进行后续的聚集操作。distribute by刚好可以做这件事。因此,distribute by经常和sort by配合使用。
cluster by:除了具有distribute by的功能外还兼具sort by的功能。但是排序只能是升序排序,不能指定排序规则为ASC或者DESC。
Q6、 hql的执行流程
第一步:输入一条HQL查询语句(eg. select * from tab)
第二步:解析器对这条Hql语句进行语法分析。
第三步:编译器对这条Hql语句生成HQL的执行计划。
第四步:优化器生成最佳的Hql的执行计划。
第五步:执行这条最佳Hql语句。
Q7、 multi group by的好处,举例说明
multi group by 可以将查询中的多个group by操作组装到一个MapReduce任务中,起到优化作用
例子:
select Provice,city,county,count(rainfall) from area where data=“2018-09-02” group by provice,city,count
select Provice,count(rainfall) from area where data=“2018-09-02” group by provice
#使用multi group by
from area
insert overwrite table temp1
select Provice,city,county,count(rainfall) from area where data=“2018-09-02” group by provice,city,count
insert overwrite table temp2
select Provice,count(rainfall) from area where data=“2018-09-02” group by provice
使用multi group by 之前必须配置参数:
hive.multigroupby.singlemr
true
Q8、 hive调优的思路
1 好的模型设计
2 解决数据倾斜
3 减少job数
4 设置合理的map reduce的task数
5 对小文件进行合并
6 单个作业最优不如整体最优
Q9、 hive中大表和小表join要注意什么?
开启map join, 然后设置合适的split的大小,来增加到合适的mapper数量
Q10、 hive有哪些udf函数,作用
UDF(user-defined function)作用于单个数据行,产生一个数据行作为输出。(数学函数,字
符串函数)
UDAF(用户定义聚集函数 User- Defined Aggregation Funcation):接收多个输入数据行,并产生一个输出数据行。(count,max)
UDTF(表格生成函数 User-Defined Table Functions):接收一行输入,输出多行(explode) 1. 个数统计函数: count
2. 总和统计函数: sum
3. 平均值统计函数: avg
4. 最小值统计函数: min
5. 最大值统计函数: max
6. 非空集合总体变量函数: var_pop
7. 非空集合样本变量函数: var_samp
8. 总体标准偏离函数: stddev_pop
9. 样本标准偏离函数: stddev_samp
10.中位数函数: percentile
11. 中位数函数: percentile
12. 近似中位数函数: percentile_approx
13. 近似中位数函数: percentile_approx
14. 直方图: histogram_numeric
15. 集合去重数:collect_set
16. 集合不去重函数:collect_list
表格生成函数 Table-Generating Functions (UDTF)
- 数组拆分成多行:explode(array)
- Map 拆分成多行:explode(map)
Q11、 hive中使用drop table数据能恢复吗?
可以恢复
如果是外部表的话这个语句不会删除表中的数据只需要重新建表关联hdfs的数据目录就可以了
如果是内部表的话,则需要提前配置hdfs的回收站,当删除hive中表的时候会将表的数据放置到hdfs的回收站中,只需要从回收站还原即可 hdfs dfs –mv ………
Q12、 Hive如何实现in和not in
In的实现:
Hive中的in的实现方式很多,简单说几种:
1) 用left semi join实现
2) 用left outer join+is not null实现
3) Inner join实现
Not in的实现:
Left outer join+is null
举例说明:
有两个表如下:
skim表
userId itemId time
001 342 2015-05-08
002 382 2015-05-09
003 458 2015-05-09
004 468 2015-05-09
buy表
userId itemId time
001 342 2015-05-07
002 382 2015-05-08
003 458 2015-05-09
005 325 2015-05-09
IN实现:
如果要查询在skim表中并且也在buy表中的信息,需要用in查询,hive sql如下:
select skim.userId , skim.itemId from skim left outer join buy
on skim.userId = buy .userId and skim.itemId = buy .itemId where buy .userId is not null;
或
select skim.userId , skim.itemId from skim left semi join buy
on skim.userId = buy .userId and skim.itemId = buy .itemId;
或
select skim.userId , skim.itemId from skim join buy
on skim.userId = buy .userId and skim.itemId = buy .itemId;
结果如下:
userId itemId
001 342
002 382
003 458
NOT IN实现:
如果要查询在skim表中并且不在buy表中的信息,需要用not in查询,hive sql如下:
select skim.userId, skim.itemId from skim left outer join buy
on skim.userId=buy .userId and skim.itemId=buy .itemId where buy .userId is null;
结果如下:
userId itemId
004 468
Q13、 简要描述数据库中的 null,说出null在hive底层如何存储,并解释selecta.* from t1 a left outer join t2 b on a.id=b.id where b.id is null; 语句的含义
null与任何值运算的结果都是null, 可以使用is null、is not null函数指定在其值为null情况下的取值。
null在hive底层默认是用’\N’来存储的,可以通过alter table test SET SERDEPROPERTIES(‘serialization.null.format’ = ‘a’);来修改。