大表join小表的时候,由于on字段存在大量的空值,进行hash分佣的时候,会将key为null或者空值的字段分发到同一个reduce,造成数据倾斜,
解决思路:将空值的字符串加上随机数,进行join,这样就会把数据通过hash分发到不同的reduce上,避免数据倾斜,列cast(concat('00000',floor(rand()*1000000)) as bigint)
mapjoin,join操作在map阶段完成,如果需要的数据在map过程中可以访问则不需要进行reduce,
小表join大小的时候,应该指定小表,这样就会把小表加载在内存,进行map端的jion,避免reduce join
指定小表/*MAPJOIN(smallTableName)*/
自动选择小表:set.hive.auto.convert.join = true;默认是false,该参数设置为true,hive将自动对左边表进行统计,自动判断是否将小表加载到内存中
大表小表的阀值:hive.mapjoin.smalltable.filesize= 25000000;默认是25mb;
hive.mapjoin.followby.gby.localtask.max.memory.usage=0.55;在map join的时候进行group by操作时候,可以使用多大的内存来存储数据,如果数据太大,则不会保存到内存里,
hive.mapjoin.localtask.max.memory.usage=0.90;说明,在本地进行map join的时候,使用的内存占比
group by存在的数据倾斜;聚合部分是发生在map端,最后在reduce端得出最终的结果,这种事基于hash的,
参数设置:hive.map.aggr=true;是否进行map端的聚合操作,
hive.groupby.mapaggr.checkinterval=100000;在map端进行聚合的条目数;
默认情况下,map阶段同一个key会发送到同一个reduce,如果key分布不均匀,造成数据倾斜,
解决思路:hive.groupby.skewindata=false;设置为true;当设置该参数为true的时候,会有2个mr job,第一个mr job,在map阶段,会将同一个key发送到不同的reduce中去(为了负载均衡),第二个mr job,map端的同一个key会发送到同一个reduce中去 ,最终得到最终的结果,
count(distint);查询执行计划可知,此操作是需要进行group by进行聚合的,,当该字段存在大量的空值,就会造成数据倾斜.
解决思路:count(distinct)时,将值为空的数据在where过滤,在最后的结果+1
列:cast(count(distinct user_id)+1 as bigint) ....where user_id is not null
笛卡尔积:尽量避免笛卡尔积,join的时候不加on条件,或者无效on条件,hive中只能是由一个reduce来完成