跑sql的时候会出现的参数:
In order to change the average load for a reducer (in bytes):
set hive.exec.reducers.bytes.per.reducer=<number> #########
如果大于<number>,就会多生成一个reduce
<number> =1024 <1k 一个reduce
1m 10个reduce
set hive.exec.reducers.bytes.per.reducer=20000;
select user_id,count(1) as order_cnt
from orders group by user_id limit 10;
--结果number of mappers: 1; number of reducers: 1009
In order to limit the maximum number of reducers:
set hive.exec.reducers.max=<number>
set hive.exec.reducers.max=10; ############
-- number of mappers: 1; number of reducers: 10
In order to set a constant number of reducers:
set mapreduce.job.reduces=<number>
set mapreduce.job.reduces=5;
--number of mappers: 1; number of reducers: 5
set mapreduce.job.reduces=15; ###########
--number of mappers: 1; number of reducers: 15
对你当前窗口,或者执行任务(脚本)过程中生效
上面这几条属性(#标识的),是后面的优先级大于前面的,即范围越小优先级越大。
##set 的属性只对你当前的窗口,或者脚本生效。
2)where条件使得group by冗余 (即有一个mapred)
map 和 reduce执行过程是一个同步的过程
同步:打电话
异步:发短信
1:map执行完 reduce在执行 1+2=》3:reduce
2:map reduce
map 60% reduce=3% #有的时候会出现这种情况,实际上也是同步的。
3)只有一个reduce
a.没有group by
set mapreduce.job.reduces=5;
select count(1) from orders where order_dow='0';
--number of mappers: 1; number of reducers: 1
b.order by
set mapreduce.job.reduces=5;
select user_id,order_dow
from orders where order_dow='0'
order by user_id
limit 10;
-- number of mappers: 1; number of reducers: 1
笛卡尔积
join没有on的条件关联。
1 1
2 1
3 1
1 2
2 2
3 2
1 3
2 3
3 3
相当于一个对一个全对上,一个不落。
用途:user product(库中所有商品中调小部分觉得这个用户喜欢 召回(match) 候选集1000) top10
users 母婴类 products
要同时考虑users和products信息来给它们做一个筛选(粗粒度)
select * from tmp_d
join (select * from tmp_d)t
where tmp_d.user_id=t.user_id; --相当于on
mapjoin
维度表:product,之类的,一般数据都不会太大。可以认为是小表。
若所有表中只有一张小表,那可在最大的表通过Mapper的时候将小表完全放到内存中,Hive可以在map端执行连接过程,称为map-side join,这是因为Hive可以和内存的小表逐一匹配,从而省略掉常规连接所需的reduce过程。即使对于很小的数据集,这个优化也明显地要快于常规的连接操作。其不仅减少了reduce过程,而且有时还可以同时减少Map过程的执行步骤。
select /*+ MAPJOIN(aisles) */ a.aisle as aisle,p.product_id as product_id
from aisles a join products p
on a.aisle_id=p.aisle_id limit 10;
##aisles为小表,将他放入到内存中。 /*+ MAPJOIN(aisles) */相当于标记下,告诉hive这是小表。
设置参数:
开启:
set hive.auto.convert.join=true; #hive1.2.2以后默认开启。
默认值:false。该参数为true时,Hive自动对左边的表统计量,若是小表就加入内存,即对小表使用Map join
开启
set hive.mapjoin.smalltable.filesize=25000000;
默认值:25M
union all/distinct=union 的优化
http://www.w3school.com.cn/sql/sql_union.asp
合并两个表,union all 不去重,union去重。前提列数一致,类型相同。
例子1
select count(distinct order_id,user_id,order_week) from (select order_id,user_id,order_week from orders where order_week='0' union all select order_id,user_id,order_week from orders where order_week='1')t;
select count(*)
from(
select order_id,user_id,order_week from orders where order_week='0' union
select order_id,user_id,order_week from orders where order_week='1')t;
!!!结论用union all 加distinct 比用union性能高。
multi insert
• Multi-insert & multi-group by
– 从一份基础表中按照不同的维度,一次组合出不同的数据 userid product_num order_num
– FROM table_name
– INSERT OVERWRITE TABLE table_name1 partition (country="US",state='1') select xxx group by key1
– INSERT OVERWRITE TABLE tablen_ame2 partition (country="US",state='2')select xxx group by key2
Automatic merge(没发调的时候选择这个)
-当文件大小比阀值小时,hive会启动一个mr进行合并
-hive.merge.mapfiles = true 是否合并Map输出文件,默认为True
-hive.merge.mapredfiles=flase 是否河滨Reduce输出文件,默认为Flase
-hive.merge.size.per.task=256*1000*1000 合并文件的大小
Multi-Count Distinct
数据倾斜
set hive.groupby.skewindata=true;
将一个map reduce拆分成两个map reduce
‘-’(‘’,-1,0,null)1亿条 到一个reduce上面,
1个reduce处理6000w ‘-’ 1% 200w求和 =》1条
29 reduce处理剩余的4000w 99%
1.随机分发到不同的reduce节点,进行聚合(count)
2. 最终的一个reduce做最终结果的聚合(200w求和 =》1条)
select add_to_cart_order,count(1) as cnt
from priors
group by add_to_cart_order
limit 10;
-- 没指定set hive.groupby.skewindata=true;
--Launching Job 1 out of 1
-- 1m 41s
--指定了set hive.groupby.skewindata=true;
--Launching Job 1 out of 2
-- 2m 50s
如果在不导致reduce一直失败起不来的时候,就不用这个变量
如果确实出现了其中一个reduce的处理数据量太多,导致任务一直出问题,运行时间长。这种情况需要设置这个变量。
凌晨定时任务,近一周报表,跑了3个小时。##数据倾斜的情况,面试的时候可以说
洗出来的基础表,3点出来,7点出来,后面接了70任务 ###数据倾斜的情况,面试的时候可以说
join顺序,map的数量
--Launching Job 1 out of 1
select
ord.order_id order_id,
tra.product_id product_id,
pri.reordered reordered
from orders ord
join trains tra on ord.order_id=tra.order_id
join priors pri on ord.order_id=pri.order_id
limit 10;
--两个MR任务
select
ord.order_id,
tra.product_id,
pro.aisle_id
from orders ord
join trains tra on ord.order_id=tra.order_id
join products pro on tra.product_id=pro.product_id
limit 10;