呼叫结果(call_result)与销售历史(sale_history)的join优化:
CALL_RESULT: 32亿条/444G

SALE_HISTORY:17亿条/439G

  • 原逻辑
    Map: 3255 Reduce: 950 Cumulative CPU: 238867.84 sec HDFS Read:
    587550313339 HDFS Write: 725372805057 SUCCESS
    28.1MIN

  • 开启中间结果压缩
    set hive.exec.compress.intermediate=true;
    set mapred.map.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec

    Map: 3255 Reduce: 950 Cumulative CPU: 268479.06 sec HDFS Read:
    587548211067 HDFS Write: 725372805057 SUCCESS
    31.6MIN
    从结果看cpu的耗时增加,这是压缩解压缩过程的消耗;HDFS读取量略有减少,可能是因为源表是RCFile存储,本身已经压缩导致,因此整体时间上没有明显减少。

  • 开启中间和最终压缩
    set hive.exec.compress.intermediate=true;
    set mapred.map.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec
    set hive.exec.compress.output=true;
    set mapred.output.compression.codec=org.apache.hadoop.io.compress.GZipCodec

    Map: 3255 Reduce: 950 Cumulative CPU: 264034.27 sec HDFS Read:
    587546058107 HDFS Write: 136021543504 SUCCESS
    24.7MIN
    从结果看HDFS write明显减少近6倍,整体运行时间有所降低

  • 设置map数量减少一倍
    set mapred.max.split.size=512000000
    Map: 1684 Reduce: 950 Cumulative CPU: 191656.39 sec HDFS Read:
    585689265249 HDFS Write: 725372805057 SUCCESS
    22.9MIN
    map数减少一倍后,消耗cpu资源减少;整体运行时间略有下降

  • 只开启JVM重用(10)
    set mapred.job.reuse.jvm.num.tasks=10;
    Map: 3255 Reduce: 950 Cumulative CPU: 259683.41 sec HDFS Read:
    587550076795 HDFS Write: 725372805057 SUCCESS
    28.9MIN
    CPU开销增加,总运行时间没有变化

  • 减少map数并设置JVM重用(10)
    Map: 1684 Reduce: 950 Cumulative CPU: 223036.3 sec HDFS Read:
    585692215905 HDFS Write: 725372805057 SUCCESS
    29.4MIN 效果不大

  • 减少map数并开启压缩
    Map: 1684 Reduce: 950 Cumulative CPU: 251331.5 sec HDFS Read:
    585697165921 HDFS Write: 136021488023 SUCCESS
    26.1MIN
    开启中间压缩,对于输入数据量有少许减少,但是cpu开销增大,对于单stage任务总体不理想

  • 减少map数并开启最终压缩
    Map: 1687 Reduce: 951 Cumulative CPU: 234941.99 sec HDFS Read:
    586512467704 HDFS Write: 136164828062 SUCCESS
    24.8MIN
    只开启结果压缩,cpu资源消耗较之前有所减少,写入数据量明显降低,性能有提升

总体来看,效果都不明显;hive默认使用reduce side join,当两个表中有一个较小的时候可以考虑map join
,但这两个表都是大表,可以尝试使用bucket map join;基本处理方法是将两个表在join key上做hash
bucket,将较小表(sale_history)的bucket设置为较大表(call_result)的数倍。这样数据就会按照join
key做hash bucket。这样做的话,小表依然会复制到各个节点上,map
join的时候,小表的每一组bucket加载成hashtable,与对应的大表bucket做局部join。
如果两表的join key 都具有唯一性(是主键关联),还可以进一步做sort merge bucket map join
;做法是两表都做bucket的基础上,每个bucket内部还要进行排序,这样做得好处就是在两边的bucket要做局部join的时候,用类似merge
sort算法中的merge操作一样把两个bucket顺序遍历一下即可。
然而以上两种方法经过测试依然没有太好的性能表现;稳定在20min之内已经不错了,又要考虑从源库抽取数据如何保留等问题,最终无法采用,后经过和业务系统沟通,两表每天数据量巨大,业务系统不会更新历史数据,每个表当天的数据是一一对应的,即当天的呼叫和销售历史是对应的,因此将程序优化为当天增量数据关联,数据下降几个数量级,自然不存在性能问题;

所以,优化无止境,不一定非技术手段不可,首先基于业务逻辑做优化,要做到业务与技术相结合。

hive两大表关联优化试验的更多相关文章

  1. Hive中小表与大表关联(join)的性能分析【转】

    Hive中小表与大表关联(join)的性能分析 [转自:http://blog.sina.com.cn/s/blog_6ff05a2c01016j7n.html] 经常看到一些Hive优化的建议中说当 ...

  2. 20亿与20亿表关联优化方法(超级大表与超级大表join优化方法)

    记得5年前遇到一个SQL.就是一个简单的两表关联.SQL跑了几乎相同一天一夜,这两个表都非常巨大.每一个表都有几十个G.数据量每一个表有20多亿,表的字段也特别多. 相信大家也知道SQL慢在哪里了,单 ...

  3. Oracle两张表关联批量更新其中一张表的数据

    Oracle两张表关联批量更新其中一张表的数据 方法一(推荐): UPDATE 表2 SET 表2.C = (SELECT B FROM 表1 WHERE 表1.A = 表2.A) WHERE EXI ...

  4. MsSql 游标 修改字段两个表关联 表向另个表插入记录

    -- 方法1:游标-- 声明变量DECLARE @SystemUserId AS UNIQUEIDENTIFIER -- 声明游标DECLARE C_SystemUser CURSOR FAST_FO ...

  5. cmds系统数据库源端大表数据更新优化

    cmds系统数据库源端大表数据更新优化 以下脚本可以用于将表按照rowid范围分区,获得指定数目的rowid Extent区间(Group sets of rows in the table into ...

  6. Mongoose 两个表关联查询aggregate 以及 Mongoose中获取ObjectId

    Mongoose 两个表关联查询aggregate 通常两个表关联查询的时候,是一种一对多的关系,比如订单与订单详情就是一对多的关系,一个订单下面有多个商品 数据模拟 首先我们先将数据模拟出来,先选择 ...

  7. Oracle SQL性能优化 - 根据大表关联更新小表

    需求: 小表数据量20w条左右,大表数据量在4kw条左右,需要根据大表筛选出150w条左右的数据并关联更新小表中5k左右的数据. 性能问题: 对筛选条件中涉及的字段加index后,如下常规的updat ...

  8. 两张超级大表join优化

    一个简单的两表关联,SQL跑了差不多一天一夜,这两个表都非常巨大,每个表都有几十个G,数据量每个表有20多亿,表的字段也特别多. 相信大家也知道SQL慢在哪里了,单个进程的PGA 是绝对放不下几十个G ...

  9. 对现有Hive的大表进行动态分区

    分区是在处理大型事实表时常用的方法.分区的好处在于缩小查询扫描范围,从而提高速度.分区分为两种:静态分区static partition和动态分区dynamic partition.静态分区和动态分区 ...

随机推荐

  1. linux中,查看某个命令是来自哪个RPM包或者是通过哪个RPM包安装的

    需求描述: 今天在测试ssh命令到底是哪个RPM包,安装之后生成的,找了一些文档 在这里进行记录下,主要是rpm -qf命令的使用,查询文件在哪个包里. 操作过程: 1.通过whereis 定位ssh ...

  2. 超全面的JavaWeb笔记day18<事务&连接池&DBUtils>

    1.事务 ACID 原子性 一致性 隔离性 持久性 mysql中开启和关闭事务 开启事务:START TRANSACTION 结束事务 提交事务:COMMIT 回滚事务:ROLLBACK JDBC中开 ...

  3. Effective C++ Item 19 Treat class design as type design

    Too high class topic for me now ................... ................... ................... fill the ...

  4. JavaScript作用域原理——预编译

    JavaScript是一种脚本语言, 它的执行过程, 是一种翻译执行的过程.并且JavaScript是有预编译过程的,在执行每一段脚本代码之前, 都会首先处理var关键字和function定义式(函数 ...

  5. UVa 10905 - Children's Game(求多个正整数排列后,所得的新的数字的极值)

    4thIIUCInter-University Programming Contest, 2005 A Children’s Game Input: standard input Output: st ...

  6. dialog里面数据更新问题

    在实际开发中经常会用到showDialog(int id)的方法来展示一个对话框,但是会遇到一个Dialog展示之后下次再show的时候对话框的界面还是上次展示的那个,而不是我们想象的界面.很多时候我 ...

  7. MQTT的学习研究(八)基于HTTP DELETE MQTT 订阅消息服务端使用

    HTTP DELETE 订阅主题请求协议和响应协议http://publib.boulder.ibm.com/infocenter/wmqv7/v7r0/topic/com.ibm.mq.csqzau ...

  8. Ubuntu14.04下安装DevStack

    虚拟机中的网络配置 NET8 为nat net2 为host-only 虚拟机网络配置 # The primary network interface vmnet nat type auto eth0 ...

  9. 封装JDBC工具类

    JDBC连接数据库基本的步骤是固定的,这样就可以考虑封装一个工具类来简化数据库操作. 封装时用到了Java中的properties配置文件,是以一种键值对的形式存在的,可以把连接数据库要动态的信息保存 ...

  10. ubuntu 创建桌面快捷方式

    $sudo apt-get install gnome-panel $gnome-desktop-item-edit  /home/xxx/桌面 --create-new 命令行:填入程序名称,如/u ...