大数据学习之路,hive的优化以及函数包的导入(4)

hive的四大by

order by (全局排序)

例子:

select * from emp order by sal;

只有一个reduce,无论设置多少个reduce,都是一个
优点:全局排序
缺点:当数据量大的时候,耗时长,效率低适用较小数据量的场景

sort by (分区内排序)

对每一个reduce内部的数据进行排序,全局结果来说不是排序的,也就是说只能保证每一个reduce输出的文件中的数据是按照规定字段排序的,适用于数据量大,但是对排序要求不严格的场景,可以大幅提高执行效率;

set mapreduce.job.reducers=10

例子:

select * from emp sort by sal desc;

需要预先设置reduce个数,reduce结果文件内部有序,全局不是,可能是无序的;

distribute by (分区排序)

控制特定的key到指定的reducer,方便后续的聚合操作,类似于MR中自定义分区,一般结合sort by 使用,需要预先设置reduce个数,否则不会启动相应的reducer进行任务的执行,导致最后不能完全分区。

set mapreduce.job.reducers=10

例子:

select * from emp distribute by deptno sort by sal desc;

注意:
1.distribute by要在sort by 之前
2.distribute by的分区规则是根据分区字段的hash码与reduce的个数去模后,余数相同的分到一个分区;

cluster by

当distribute by 和sort by 字段相同的时候,可以写成cluster by
但是这个排序只能升序;

select * from emp cluster by deptno;
select * from emp distribute by deptno sort by deptno;
题目

有一张订单表,然后取gmv为top 100 的用户,假设这张订单表有1亿的用户有gmv,求如何去取;
第一种:

select * from dwd_order_df order by gmv desc limit 100;

弊端:全局排序显然不行,耗时长,效率低;
所以可不可以多个reduce,分区内排序,最后再全局排序呢;

select * from (
select * from dwd_order_df  distribute by city sort by gmv desc limit 100) x
order by gmv desc limit 100;

hive 的三大join

common/shuffle/reduce join

最普通的join,产生shuffle,且这个会在reduce端做join

mapjoin

通常用在大小表关联
小表的阈值

set hive.mapjoin.smalltable.filesize=25123456;--25M
select /*+MAPJOIN(b)*/ count(1)
from a  --大表
join b   --小表
on a.id=b.id

可以将b表放在内存,在map端做join,join就发生在map操作的时候,每当扫描一个大表的数据,就要去内存看小表,有没有与之相等的,继而进行关联。
优点:map端的join优势,没有shuffle;
还一种写法,自动将小表扔到内存中;

set hive.auto.convert.join=true;
select  count(1)
from a
join b
on a.id=b.id;
SMB join

sort merge bucket
大表和大表关联呢?
a 5亿
b 10亿
1.a b 都是分桶的
2.a b 分桶的key必须是join key
3.设置一些参数

set hive.auto.convert.sortmerge.join=true;
set hive.optimize.bucketmapjoin=true;
set hive.optimize.bucketmapjoin.sortedmerge=true;

hive的参数优化

mapjoin
set hive.mapjoin.smalltable.filesize=25123456;
set hive.auto.convert.join=true;
combiner 在map端聚合
set hive.map.aggr=true;

在map端进行聚合的条数

set hive.groupby.mapaggr.checkinterval=100000;
负载均衡

数据倾斜的时候

set hive.groupby.skewindata =true;

当选定为true,生成的查询计划会产生两个MR 的job
1.先加随机前缀,聚合一次;
2.再去掉随机前缀,在聚合一次;

UDF

实现一个简单的UDF

select say_hello('word');
hello:world

java实现:
第一步在pom.xml文件里面,导入hive包依赖

 <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-exec</artifactId>
            <version>3.1.2</version>
        </dependency>

第二步,建class,实现方法

package hiveUDF;

import org.apache.hadoop.hive.ql.exec.UDF;

public class UDFHello extends UDF {
    public String evaluate(String name){
        return "Hello : " + name;
    }
}

然后进行打包,上传服务器hive/lib,赋权

[root@vagary lib]# rz
[root@vagary lib]# chmod 777 mapreduce-1.0.jar

进入hive,添加jar包


hive (default)> add jar /home/vagary/app/hive/lib/mapreduce-1.0.jar ;
Added [/home/vagary/app/hive/lib/mapreduce-1.0.jar] to class path
Added resources: [/home/vagary/app/hive/lib/mapreduce-1.0.jar]

然后看一下jar包

hive (default)> list jars;
/home/vagary/app/hive/lib/mapreduce-1.0.jar

接下来创建函数

hive (default)> CREATE TEMPORARY FUNCTION say_hello as "hiveUDF.UDFHello";
OK
Time taken: 0.578 seconds

然后测试一下

hive (default)> select say_hello('world');
OK
_c0
Hello : world
Time taken: 2.556 seconds, Fetched: 1 row(s)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值