Hive.LEFT SEMI JOIN子句

转载:https://blog.csdn.net/mashroomxl/article/details/20845279

公司的数据仓库和离线数据分析是建立在Hadoop + Hive基础上的,现在的工作主要是数据分析,自然也就跟HQL查询经常打交道了。刚来公司几乎完全不懂数据库知识,神马结构化查询语言也只是听说而已,不过,这没关系,实际工作一来,学习起来还是很快~~

        年前有一个同事叫帮忙查某个产品的月度留存UV这个数据,当时业务不熟,还去参照了一下别人是怎么定义留存用户这个指标的。。。然后根据自己的理解,用下面这种形式(其实刚开始的逻辑写得比这个还拙计,我不会到处乱说)的脚本逻辑去查:

  1. SELECT
  2. t1.产品类型,
  3. COUNT( DISTINCT ( IF(t2.用户 ID IS NULL, NULL, t1.用户 ID))) AS KEEP_UV
  4. FROM
  5. (
  6. SELECT
  7. 产品类型,
  8. 用户 ID
  9. FROM 事实表
  10. WHERE ( `DATE` >= 20140201 AND `DATE` <= 20140228)
  11. ) t1
  12. LEFT OUTER JOIN
  13. (
  14. SELECT
  15. 产品类型,
  16. 用户 ID
  17. FROM 事实表
  18. WHERE ( `DATE` >= 20140101 AND `DATE` <= 20140131)
  19. ) t2 ON (t1.产品类型 = t2.产品类型 AND t1.用户 ID = t2.用户 ID)
  20. GROUP BY t1.产品类型
        

       但是,这个事实表本身所包含的字段很多,信息量很大,加上时间跨度为2个月,当时就想会不会略慢,结果跑起来果然慢得很,Map或者Reduce的任务经常卡在某个百分点比较久时间。

       看着MapReduce像蜗牛一样行进着,我才忽然想到在官方Wiki上貌似看到过这种 IN / EXISTS子查询(准确地说,这里是非相关子查询)有一种高效的实现,就是LEFT SEMI JOIN:

       LEFT SEMI JOIN implements the uncorrelated IN/EXISTS subquery semantics in an efficient way.

       于是抱着试一试的心态,马上修改脚本,用下面的形式去跑:

  1. SELECT
  2. 产品类型,
  3. COUNT( DISTINCT t1.用户 ID) AS KEEP_UV
  4. FROM
  5. (
  6. SELECT
  7. 产品类型,
  8. 用户 ID
  9. FROM 事实表
  10. WHERE ( `DATE` >= 20140201 AND `DATE` <= 20140228)
  11. ) t1
  12. LEFT SEMI JOIN
  13. (
  14. SELECT
  15. 产品类型,
  16. 用户 ID
  17. FROM 事实表
  18. WHERE ( `DATE` >= 20140101 AND `DATE` <= 20140131)
  19. ) t2 ON (t1.产品类型 = t2.产品类型 AND t1.用户 ID = t2.用户 ID)
  20. GROUP BY 产品类型

       果然,第2种脚本很快就出来结果了,而第1种脚本还在某个百分点艰难地挪步。。。

       值得注意的是,用了LEFT SEMI JOIN子句以后,右边的表在JOIN操作以外就不可见了,也就是说,右边的表只能在对应的ON子句中被引用。
       以上只是直观的感觉,从定性的层面感受到LEFT SEMI JOIN方式的性能真的是很不错,不晓得这样的效果除了来自Hive本身的官方高效实现外,与公司的生产环境有没有关系。。。
       怎么样,是不是想看看Hive这种特有的方式究竟为我们的查询带来了多大的时间效能改进?是不是也想看看它在源码里究竟是怎样的实现?行动起来吧。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值