zoukankan      html  css  js  c++  java
  • Hive 作业优化

    1、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) ;


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

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

    3、控制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.


    4、设置合理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;


    •reduce个数并不是越多越好

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

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

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


    5、合并MapReduce操作

    • 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 子句中设置过滤条件。



    7、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

  • 相关阅读:
    IIS部署Asp.Net Core 项目运行时报错,处理程序“aspNetCore”在其模块列表中有一个错误模块“AspNetCoreModuleV2"
    Linux Mysql5.7.22安装
    Nginx初体验
    asp.net core Csc任务不支持SharedCompilationId参数,请确认改参数存在于此任务中,并且是可设置的公共实例属性
    【Node.js 】Express框架
    【Node.js】 初体验
    Mongodb 配置
    【C#】Windows服务守护并发送邮件通知
    新建【Git】仓库后给使用者授权
    Git提交修改的代码出现提交不上去
  • 原文地址:https://www.cnblogs.com/Allen-rg/p/9273390.html
Copyright © 2011-2022 走看看