首页 > 代码库 > Hive语法层面优化之六数据倾斜常见案例

Hive语法层面优化之六数据倾斜常见案例

常见案例一:空值产生的数据倾斜

日志表有一部分的user_id为空或者是0的情况,导致在用user_id进行hash分桶时,会将日志由user_id为0或者为空的数据分到一个reduce上,导致数据倾斜;

如:访户未登录时,日志中的user_id为空,用user_id和用户表的user_id进行关联的时候,会将日志中的user_id为空的数据分到一起,导致了过大的空key造成数据倾斜;

 

解决办法:随机函数解决数据倾斜

把空值的key变成一个字符串加上随机数(只要不与真正的end_user_id的格式相同即可),把倾斜的数据分发到不同的reduce上,由于null值关联不上用户表,处理后并不影响最终结果

        

案例: end_user 5000W数据,维度表; trackinfo 每日2亿,按日增量表;

原写法:

select u.id,  t.url,  t.track_time   from  end_user ujoin(select end_user_id,  url,  track_time   from trackinfo where ds=‘2013-12-01‘) ton u.id=t.end_user_id limit 2;

注意事项:where条件最好别放在最后,而是放到某个子查询中或者on前,可以事先过滤掉一批数据

调整为:

select u.id, t.url, t.track_time from end_user ujoin(select   case when end_user_id=‘null‘ or end_user_id is null   then cast (concat(‘00000000‘,floor(rand()*1000000)) as bigint)   else end_user_id end as end_user_id ,  url,track_time from trackinfo where ds=‘2013-07-21‘) ton u.id=t.end_user_id limit 2;

在相同的集群中测试发现:后一种的写法比前一种的写法快差不多2倍;

 

CASE … WHEN … THEN Statements 案例:

SELECT empno, ename, sal,  CASE  WHEN sal <  1000.0 THEN ‘low‘  WHEN sal >= 1000.0 AND sal <  1500.0 THEN ‘middle‘  WHEN sal >= 1500.0 AND sal < 2000.0 THEN ‘high‘  ELSE ‘very high‘  END AS salary FROM emp;    7369    SMITH   800.0   low7499    ALLEN   1600.0  high7521    WARD    1250.0  middle7566    JONES   2975.0  very high7654    MARTIN  1250.0  middle7698    BLAKE   2850.0  very high7782    CLARK   2450.0  very high7788    SCOTT   3000.0  very high7839    KING    5000.0  very high7844    TURNER  1500.0  high7876    ADAMS   1100.0  middle7900    JAMES   950.0   low7902    FORD    3000.0  very high7934    MILLER  1300.0  middle