设为首页 加入收藏

TOP

hql优化教程(二)
2018-10-23 18:08:36 】 浏览:420
Tags:hql 优化 教程
条,打上标签b,变成两个 对, 。所以商品表的hdfs读只会是一次。

问题5:先join生成临时表,在union all还是写嵌套查询,这是个问题。比如以下例子:

Select *

From (select *

From t1

Uion all

select *

From t4

Union all

Select *

From t2

Join t3

On t2.id = t3.id

) x

Group by c1,c2;

这个会有4个jobs。假如先join生成临时表的话t5,然后union all,会变成2个jobs。

Insert overwrite table t5

Select *

From t2

Join t3

On t2.id = t3.id

;

Select * from (t1 union all t4 union all t5) ;

hive在union all优化上可以做得更智能(把子查询当做临时表),这样可以减少开发人员的负担。出现这个问题的原因应该是union all目前的优化只局限于非嵌套查询。如果写MR程序这一点也不是问题,就是multi inputs。

问题6:使用map join解决数据倾斜的常景下小表关联大表的问题,但如果小表很大,怎么解决。这个使用的频率非常高,但如果小表很大,大到map join会出现bug或异常,这时就需要特别的处理。云瑞和玉玑提供了非常给力的解决方案。以下例子:

Select * from log a

Left outer join members b

On a.memberid = b.memberid.

Members有600w+的记录,把members分发到所有的map上也是个不小的开销,而且map join不支持这么大的小表。如果用普通的join,又会碰到数据倾斜的问题。

解决方法:

Select /*+mapjoin(x)*/* from log a

Left outer join (select /*+mapjoin(c)*/d.*

From (select distinct memberid from log ) c

Join members d

On c.memberid = d.memberid

)x

On a.memberid = b.memberid。

先根据log取所有的memberid,然后mapjoin 关联members取今天有日志的members的信息,然后在和log做mapjoin。

假如,log里memberid有上百万个,这就又回到原来map join问题。所幸,每日的会员uv不会太多,有交易的会员不会太多,有点击的会员不会太多,有佣金的会员不会太多等等。所以这个方法能解决很多场景下的数据倾斜问题。

问题7:HIVE下通用的数据倾斜解决方法,double被关联的相对较小的表,这个方法在mr的程序里常用。还是刚才的那个问题:

Select * from log a

Left outer join (select /*+mapjoin(e)*/

memberid, number

From members d

Join num e

) b

On a.memberid= b.memberid

And mod(a.pvtime,30)+1=b.number。

Num表只有一列number,有30行,是1,30的自然数序列。就是把member表膨胀成30份,然后把log数据根据memberid和pvtime分到不同的reduce里去,这样可以保证每个reduce分配到的数据可以相对均匀。就目前测试来看,使用mapjoin的方案性能稍好。后面的方案适合在map join无法解决问题的情况下。

长远设想,把如下的优化方案做成通用的hive优化方法

1. 采样log表,哪些memberid比较倾斜,得到一个结果表tmp1。由于对计算框架来说,所有的数据过来,他都是不知道数据分布情况的,所以采样是并不可少的。Stage1

2. 数据的分布符合社会学统计规则,贫富不均。倾斜的key不会太多,就像一个社会的富人不多,奇特的人不多一样。所以tmp1记录数会很少。把tmp1和members做map join生成tmp2,把tmp2读到distribute file cache。这是一个map过程。Stage2

3. map读入members和log,假如记录来自log,则检查memberid是否在tmp2里,如果是,输出到本地文件a,否则生成 的key,value对,假如记录来自member,生成 的key,value对,进入reduce阶段。Stage3.

4. 最终把a文件,把Stage3 reduce阶段输出的文件合并起写到hdfs。

这个方法在hadoop里应该是能实现的。Stage2是一个map过程,可以和stage3的map过程可以合并成一个map过程。

这个方案目标就是:倾斜的数据用mapjoin,不倾斜的数据用普通的join,最终合并得到完整的结果。用hive sql写的话,sql会变得很多段,而且log表会有多次读。倾斜的key始终是很少的,这个在绝大部分的业务背景下适用。那是否可以作为hive针对数据倾斜join时候的通用算法呢?

问题8:多粒度(平级的)uv的计算优化,比如要计算店铺的uv。还有要计算页面的uv,pvip.

方案1:

Select shopid,count(distinct uid)

From log group by shopid;

Select pageid, count(distinct uid),

From log group by pageid;

由于存在数据倾斜问题,这个结果的运行时间是非常长的。

方案二:

From log

Insert overwrite table t1 (type=’1’)

Select shopid

Group by shopid ,acookie

Insert overwrite table t1 (type=’2’)

Group by pageid,acookie;

店铺uv:

Select shopid,sum(1)

From t1

Where type =’1’

Group by shopid ;

页面uv:

Select pageid,sum(1)

From t1

Where type =’1’

Group by pageid ;

这里使用了multi insert的方法,有效减少了hdfs读,但multi insert会增加hdfs写,多一次额外的map阶段的hdfs写。使用这个方法,可以顺利的产出结果。

方案三:

Insert into t1

Select type,type_name,’’ as uid

From (

Select ‘page’ as type,

Pageid as type_name,

Uid

From log

Union all

Select ‘shop’ as type,

Shopid as type_name,

Uid

From log ) y

Group by type,type_name,uid;

Insert into t2

Select type,type_name,sum(1)

From t1

Group by type,type_name;

From t2

Insert into t3

Select type,type_name,uv

Where type=’page’

Select type,type_name,uv

Where type

首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇sql如何把一个表的查询结果插入到.. 下一篇MongoDB集群架构之分片架构

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目