MaxCompute JOIN优化小结

摘要: Join是MaxCompute中最基本的语法,但由于数据量和倾斜问题,非常容易出现性能问题。一般情况下,join产生的问题有两大类: 数据倾斜问题:join会将key相同的数据分发到同一个instance上处理,如果某个key上的数据量特别多则会导致该instance处理时间比其他instance...

原文地址:http://click.aliyun.com/m/43804/

Join是MaxCompute中最基本的语法,但由于数据量和倾斜问题,非常容易出现性能问题。一般情况下,join产生的问题有两大类:

1.数据倾斜问题:join会将key相同的数据分发到同一个instance上处理,如果某个key上的数据量特别多则会导致该instance处理时间比其他instance处理时间长,这就是我们常说的数据倾斜,这也是join计算性能问题的罪魁祸首;

2.数据量问题:关联的两表基本没有热点问题,但两个表数据量都非常大同样会影响性能,比如记录数达几十亿条,如商品表、库存表等;

虽然MaxCompute中提供了一些通用的优化算法,但从业务角度解决性能问题往往更精确,更有效。对于MaxCompute sql优化,在云栖社区上已经有比较多的经验积累,本文主要对join产生的性能问题以及解法做些总结。

不同数据类型key关联

例子

浏览IPV日志以商品id关联商品表,假设日志表的商品id字段是string类型,商品表中的商品id是bigint类型,那么在关联中,关联key会全部转换成double类型进行比较,设想由于埋点问题日志表中的商品id存在很多非数值的脏数据,那么转换成double后值都变为NULL或者截取前面的数值,关联时就会产生数据倾斜问题,更严重的会造成数据错误。

解法

关联时手工进行数据格式转换,在这种情况下一般将bigint类型key转换成string类型。

select a.*
from ipv_log_table a
left outer join item_table b
on a.item_id = cast(b.item_id as string)

思考下,假如反过来将string类型转换成bigint、假如IPV日志表中的商品id大部分为无效值(比如0)、又假如IPV日志表中没有无效值但是有热点key会有什么问题呢?下面的例子会解答这些问题。

小表join大表

Join中存在小表,一般这个小表在100M以内,可以用mapjoin,避免分发引起的长尾。拿上面的例子来说,假如商品表数据量只有几万条记录(这里只是打个比方,现实业务中商品表一般都是非常庞大的),但是IPV日志表中的商品id 80%值为0的无效值,且记录数有几十亿,如果采用上述SQL写法,数据倾斜是显而易见的,但利用mapjoin可以有效解决这个问题:

select /*+ MAPJOIN(b) */a.*
from ipv_log_table a
left outer join item_table b
on a.item_id = cast(b.item_id as string)

mapjoin原理

把小表广播传递到所有的Join Task Instance上面,然后直接和大表做Hash Join,简单的说就是将join操作提前到map端,而非reduce端。

mapjoin使用注意点

小表在left outer join 时只能是右表, right outer join 时只能是左表, inner join 时无限制,full outer join不支持mapjoin;
mapjoin最多只支持8张小表,否则会报语法错误;
mapjoin所有小表内存限制不能超过2GB,默认为512M;
mapjoin支持小表为子查询;
mapjoin支持不等值连接或者使用or连接多个条件;

大表join大表存在无效值

在小表join大表时我们已经了解到通过mapjoin将小表全部加载到map端可以解决倾斜问题,但假如‘小表‘不够小,mapjoin失效的时候该怎么办呢?同样以本文第一个场景为例,IPV日志表中80%商品id都为无效值0(目前MaxCompute底层已经针对NULL值进行优化,已经不存在倾斜问题了),这时关联十几亿量级商品表那就是个灾难。

解法1-分而治之:
我们可以事先知道无效值是不可能关联出结果的,而且完全不需要参与关联,所以可以将无效值与有效值数据分开处理:

select a.visitor_id
      ,b.seller_id
from (
      select
      from ipv_log_table
      where item_id > 0
) a
left outer join item_table b
on a.item_id = b.item_id

union all

select a.visitor_id
      ,cast(null as bigint) seller_id
from ipv_log_table
where item_id = 0

解法2-随机值打散:
我们也可以以随机值代替NULL值作为join的key,这样就从原来一个reduce来处理倾斜数据变成多reduce并行处理,因为无效值不参与关联,即使分发到不同reduce,也不会影响最终计算结果:

select a.visitor_id
      ,b.seller_id
from ipv_log_table a
left outer join item_table b
on if(a.item_id > 0, cast(a.item_id as string), concat(‘rand‘,cast(rand() as string))) = cast(b.item_id as string)

解法3-转化为mapjoin:
虽然商品表有十几亿条记录,不能直接通过mapjoin来处理,但在实际业务中,我们知道一天内用户访问的商品数是有限的,在业务中尤为明显,基于此我们可以通过一些处理转换成mapjoin:

select /*+ MAPJOIN(b) */
       a.visitor_id
      ,b.seller_id
from ipv_log_table a
left outer join (
   select /*+ MAPJOIN(log) */
         itm.seller_id
        ,itm.item_id
   from (
         select item_id
         from ipv_log_table
         where item_id > 0
         group by item_id
   ) log join item_table itm
   on log.item_id = itm.item_id
) b
on a.item_id = b.item_id

解法对比

解法1和解法2是通用解决方案,对于解法1,日志表被读取两次,而解法2中只需读取一次,另外任务数解法2也是少于解法1的,所以总的来看解法2是优于解法1的。解法3是基于一定的假设,随着业务发展或者某些特殊情况下假设可能失效(比如一些爬虫日志,可造成访问商品数接近全量),这会导致mapjoin失效,所以在使用过程中要根据具体情况来评估。

一个古老的例子

最后要讲一个古老的优化case,虽然历史比较久远,目前已没有相关问题,但优化思路值得借鉴。情况是这样的,历史上并存过两套商品维表,一份主键是字符串id,新的商品表也就是目前在使用的主键是数字id,字符串id和数字id做了映射,存在商品表中的两个字段中,所以在使用中需要分别过滤数字id、字符串id然后分别和商品表关联,最后union起来得到最终结果。

思考下如果换成下面的优化思路是不是更优呢?

select ...
from ipv_log_table a
join (
      select auction_id as auction_id
      from auctions
      union all
      select auction_string_id as auction_id
      from auctions
      where auction_string_id is not null
) b
on a.auction_id = b.auction_id

答案是肯定的,可以看到优化后商品表读取从2次降为1次,IPV日志表同样,另外MR作业数也从2个变为1个。

总结
对于MaxCompute sql优化最有效的方式是从业务的角度切入,并能够将MaxCompute sql转化为mapreduce程序来解读。本文针对join中各种场景优化都做了一些梳理,现实情况很可能是上述多场景的组合,这时候就需要灵活运用相应的优化方法,举一反三。

识别以下二维码,阅读更多干货

原文地址:http://blog.51cto.com/13641484/2087113

时间: 2024-10-11 00:36:32

MaxCompute JOIN优化小结的相关文章

只需四步,帮助企业做好MaxCompute成本优化

摘要: 阿里云在和很多企业交流的过程中发现他们在使用MaxCompute的时候往往会遇到一些成本相关的问题,而在与客户不但交流沟通的过程中,阿里云在成本优化方面也积累了大量的经验,因此也希望能够将这些经验沉淀下来分享给更多的企业和开发者,本文就将与大家分享帮助企业做好MaxCompute成本优化的"四步走"战略. 摘要:阿里云在和很多企业交流的过程中发现他们在使用MaxCompute的时候往往会遇到一些成本相关的问题,而在与客户不但交流沟通的过程中,阿里云在成本优化方面也积累了大量的经

Mysql 查询技巧:使用JOIN优化子查询

1.数据准备 mysql> select * from student; +----+--------+----------+---------+-------------+ | id | name   | idCardNo | isCadre | nickname    | +----+--------+----------+---------+-------------+ |  1 | Tom    | 350020   |       1 | Big T       | |  2 | Ji

iOS性能优化小结

iOS性能优化分析 首先要熟悉几个概念 PNG 和 JPG 的区别是什么? png格式的图片有alpha通道,jpeg则没有.png无损压缩,jpeg允许你选择0-100%的压缩质量.如果需要alpha通道(透明),就只能用png格式. CPU 和 GPU 如果想看看两者的区别,先得了解iOS视图背后的层级结构原理  上图中的最底下一行是硬件层,由GPU和CPU组成. 我们经常说到的硬件加速其实是指OpenGL,Core Animation/UIKit基于GPU之上对计算机图形合成以及绘制的实现

斜率凸优化小结

斜率凸优化小结 前言 很久以前考了一道叫做"林克卡特树"的题目( 还记得被八省联考支配的恐惧吗?) 正解是用直线去切一个凸函数...... 当时并不是很会.然而\(APIO\)讲课竟然讲了并且卧槽我竟然还听懂了. 所以就回来把这个坑给填了. 斜率凸优化 当遇到关于需要恰好选取\(K\)个的\(DP\)问题的时候, 一般做法就是在\(DP\)数组上再设一维.这样做时间代价是\(O(n)\)的. 其实不如给每次选取加一个权值\(C\). 那么每次选取就需要付出\(C\)的代价.所以\(C\

[2018福大至诚软工助教]测试与优化小结

[2018福大至诚软工助教]测试与优化小结 一.得分 点击表头内相应项目可针对该项目进行排序. 学号1 学号2 单元测试10 结构优化10 性能调优10 奖励分0-3 总分30-33 6367 6445 10 10 10 2 32 6387 6354 8 7 3 0 18 6285 6314 0 0 0 0 0 6319 6321 3 0 0 0 3 6391 6380 0 0 0 1 1 6306 6308 7 3 0 0 10 6348 6338 4 0 0 0 4 6328 6331 0

css写作建议和性能优化小结

1.前言 还有几天就到国庆中秋了,快要放假了,先祝大家节日快乐!之前写过js的写作建议和技巧,那么今天就来聊聊css吧!说到css,每一个网页都离不开css,但是对于css,很多开发者的想法就是,css只要能用来布局,把效果图排出来就可以了,其它的细节或者优化,不需要怎么考虑.但是我觉得css可不只是把页面的布局完成就是完事的,还需要考虑很多细节有优化,更不会像大家想得那么简单,在学习当中,如果发现什么技巧或者优化的点,我也会学以致用!那么今天,就分享下我总结的css写作建议和性能优化的一些问题

移动web开发问题和优化小结

1.前言 到目前为止,互联网行业里,手机越来越智能化,移动端占有的比例越来越高,尤其实在电商,新闻,广告,游戏领域.用户要求越来越高,网站功能越来越好,效果越来越炫酷,这就要求我们产品质量越来越高,web前端开发而言是一个挑战,是一个难题,也是一个机遇.如何让我们所开发的手机页面能有更好的交互体验,就是这篇文章的主旨:移动web开发问题和优化小结.这个只是我自己在开发的时候知道的坑,如果大家有遇到什么别的坑,欢迎补充,或者觉得我哪里写错了,欢迎指点! 2.Meta标签 页面在手机上显示时,增加这

hive join 优化 --小表join大表

1.小.大表 join 在小表和大表进行join时,将小表放在前边,效率会高,hive会将小表进行缓存. 2.mapjoin 使用mapjoin将小表放入内存,在map端和大表逐一匹配,从而省去reduce. 例子: select /*+MAPJOIN(b)*/ a.a1,a.a2,b.b2 from tablea a JOIN tableb b ON a.a1=b.b1 在0.7版本后,也可以用配置来自动优化 set hive.auto.convert.join=true;

浅谈Flink批处理优化器之Join优化

跟传统的关系型数据库类似,Flink提供了优化器"hint"(提示)以告诉优化器选择一些执行策略.目前优化提示主要针对批处理中的连接(join).在批处理中共有三个跟连接有关的转换函数: join:默认为等值连接(Equi-join),维基百科将其归类为内连接(inner join)的一种 https://en.wikipedia.org/wiki/Join_(SQL): outerJoin:外连接,具体细分为left-outer join.right-outer join.full-