Hive 做业优化

一、Join原则
将条目少的表/子查询放在 Join的左边。 缘由是在 Join 操做的 Reduce 阶段,位于 Join左边的表的内容会被加载进内存,将条目少的表放在左边,能够有效减小发生内存溢出的概率。
当一个小表关联一个超大表时,容易发生数据倾斜,能够用MapJoin把小表所有加载到内存在map端进行join,避免reducer处理。
如:SELECT /*+ MAPJOIN(user) */  l.session_id, u.username from user u join page_views l on (u. id=l.user_id) ;


二、笛卡尔积
当Hive设定为严格模式(hive.mapred.mode=strict)时,不容许在HQL语句中出现笛卡尔积。
当没法躲避笛卡尔积时,采用MapJoin,会在Map端完成Join操做,将Join操做的一个或多个表彻底读入内存。
MapJoin的用法是在查询/子查询的SELECT关键字后面添加/*+ MAPJOIN(tablelist) */提示优化器转化为MapJoin 。数据库

其中tablelist能够是一个表,或以逗号链接的表的列表。tablelist中的表将会读入内存,应该将小表写在这里session

 

三、控制Map数
同时可执行的map数是有限的。
•一般状况下,做业会经过input的目录产生一个或者多个map任务
•主要的决定因素有: input的文件总个数,input的文件大小。


•举例
a) 假设input目录下有1个文件a,大小为780M,那么hadoop会将该文件a分隔成7个块(block为128M,6个128m的块和1个12m的块),从而产生7个map数
b) 假设input目录下有3个文件a,b,c,大小分别为10m,20m,130m,那么hadoop会分隔成4个块(10m,20m,128m,2m),从而产生4个map数

两种方式控制Map数:即减小map数和增长map数
减小map数能够经过合并小文件来实现,这点是对文件数据源来说。
增长map数的能够经过控制上一个job的reduer数来控制,见5.


oop

四、设置合理reducer个数优化

•reducer个数的设定极大影响执行效率
•不指定reducer个数的状况下,Hive分配reducer个数基于如下:
    参数1:hive.exec.reducers.bytes.per.reducer(默认为1G)
    参数2 :hive.exec.reducers.max(默认为999)
•计算reducer数的公式
•N=min(参数2,总输入数据量/参数1)
set mapred.reduce.tasks=13;.net


•reduce个数并非越多越好blog

同map同样,启动和初始化reduce也会消耗时间和资源;有多少个reduce,就会有多少个输出文件索引

Reducer数过多:
生成了不少个小文件,那么若是这些小文件做为下一个任务的输入,则也会出现小文件过多的问题。
Reducer过少:
影响执行效率。

•什么状况下只有一个reduce
 不少时候你会发现任务中无论数据量多大,无论你有没有设置调整reduce个数的参数,任务中一直都只有一个reduce任务;
一、 除了数据量小于hive.exec.reducers.bytes.per.reducer参数值的状况外
二、没有group by的汇总
三、用了Order by。


内存

五、合并MapReduce操做hadoop

• Multi-group by:当从同一个源表进行屡次查询时用。
•Multi-group by是Hive的一个很是好的特性,它使得Hive中利用中间结果变得很是方便
•FROM log资源

insert overwrite table test1 select log.id group by log.id

insert overwrite table test2 select log.name group by log.name

• 上述查询语句使用了Multi-group by特性连续group by了2次数据,使用不一样的group by key。这一特性能够减小一次MapReduce操做


6 、LEFT SEMI  JOIN

是 IN/EXISTS 子查询的一种更高效的实现。
Hive 当前没有实现 IN/EXISTS 子查询,因此你能够用 LEFT SEMI JOIN 重写你的子查询语句。LEFT SEMI JOIN 的限制是, JOIN 子句中右边的表只能在 ON 子句中设置过滤条件,在 WHERE 子句、SELECT 子句或其余地方过滤都不行。
  SELECT a.key, a.value
  FROM a
  WHERE a.key in
   (SELECT b.key
    FROM B);
能够被重写为:
   SELECT a.key, a.val
   FROM a LEFT SEMI JOIN b on (a.key = b.key)
只能在 ON 子句中设置过滤条件。



七、Hive注意事项

  • 只支持INSERT/LOAD操做,无UPDATE和DELTE
  • 0.10以前版本没有索引
  • 不支持HAVING操做。
  • 不支持where子句中的子查询
  • Join只支持等值关联
  • Hive中string类型没有长度限制

Not用法:
关系数据库:
… where username not like(in) ..
Hive
… where not username like(in)..

 

转自:https://blog.csdn.net/youfashion/article/details/72862453

相关文章
相关标签/搜索