背景
同事写了这样一段HQL(涉及公司数据,表名由假名替换,语句与真实场景略有不同,但不影响分析):
- CREATE TABLE tmp AS
- SELECT
- t1.exk,
- t1.exv,
- M.makename AS m_makename,
- S.makename AS s_makename,
- FROM
- (SELECT
- exk,
- exv
- FROM xx.xxx_log
- WHERE etl_dt = '2017-01-12'
- AND exk IN ('xxID', 'yyID') ) t1
- LEFT JOIN xx.xxx_model_info M ON (M.modelid=t1.exv AND t1.exk='xxID')
- LEFT JOIN xx.xxx_style_info S ON (S.styleid=t1.exv AND t1.exk='yyID')
任务运行过程中非常缓慢,同事反映说这个任务要跑一个多小时。初步问了下,xx.xxx_log表数据量在分区etl_dt = '2017-01-12'上大概1亿3000万,xx.xxx_model_info大概3000多,xx.xxx_style_info大概4万多。
分析
第一步,分析HQL语句着手
从同事提供的数据量上看,两个left join显然应该是mapjoin,因为数据量差距悬殊。当前只有HQL语句,所以优化第一步当然要从HQL语句本身出发,看HQL语句是否有不恰当的地方。
从语句上看,就是取三张表的数据,按条件进行join,最后创建并插入一张hive表。语句上看没什么问题。
那就来看执行计划吧~ 我们只看建表后面的SELECT语句,如下
- STAGE DEPENDENCIES:
- Stage-5 is a root stage
- Stage-4 depends on stages: Stage-5
- Stage-0 depends on stages: Stage-4
- STAGE PLANS:
- Stage: Stage-5
- Map Reduce Local Work
- Alias -> Map Local Tables:
- m
- Fetch Operator
- limit: -1
- s
- Fetch Operator
- limit: -1
- Alias -> Map Local Operator Tree:
- m
- TableScan
- alias: m