【十八掌●武功篇】第十掌:HiveSQL中分区筛选条件怎么写效率才最高

在写Hive SQL时,当遇到两个分区表a 和 b 相Join的时候,分区筛选条件怎么写效率才高呢?

有下面三种书写方式,下面就根据三个语句的执行计划分析一下,看种写法的执行效率会更高。

1、将分区筛选条件放入where中

select * from his h
left join s_test s on h.ID_1=s.ID_1
where h.dt='2018-05-07' and s.dt='2018-05-07';

点击查看第一种写法的执行计划

这种写法的执行计划,只有第一个表h在map端进行了分区字段筛选,第二个表s没有在map端进行分区筛选,而是到了reduce端才进行分区筛选,那么第二个表扫描的是所有分区的数据,并且无用的分区数据参与了计算和网络传输,明显效率非常低。

filterExpr: (dt = ‘2018-05-07’) (type: boolean)

2、将分区筛选放入on中

select * from his h
left join s_test s 
on h.ID_1=s.ID_1 and h.dt='2018-05-07' and s.dt='2018-05-07';

点击查看第二种写法的执行计划

通过查询执行计划,发现这种将dt筛选放入on后面的方式,只有第二个表s在map端进行了分区筛选,第一个表而是在reduce里进行的分区筛选,效率也非常低。

3、先根据分区筛选两个表,然后再join

select * from 
  (
    select * from his h where h.dt='2018-05-07'
  )a 
left join 
  (
    select * from s_test s where s.dt='2018-05-07'
  ) b
on a.ID_1=b.ID_1

点击查看第三种写法的执行计划

第三种方式是两个表分别在一个子查询中先进行分区筛选,然后再进行关联操作。通过查看执行计划,可以发现两个表都在map阶段进行了分区筛选,这样就能尽早地减少无用数据,效率最高。

4、遗留的疑惑

为什么在第一种写法中:

where h.dt='2018-05-07' and s.dt='2018-05-07';

只有h.dt在map阶段筛选了,而s.dt没有在map端进行筛选呢?

而第二种写法中:

on h.ID_1=s.ID_1 and h.dt='2018-05-07' and s.dt='2018-05-07';

反倒是s.dt在map阶段筛选了,h.dt没有进行筛选?

发布了74 篇原创文章 · 获赞 74 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/chybin500/article/details/80424638