hive参数hive.mapred.mode分析

Hive配置中有个参数hive.mapred.mode,分为nonstrict,strict,默认是nonstrict

如果设置为strict,会对三种情况的语句在compile环节做过滤:

1. 笛卡尔积Join。这种情况由于没有指定reduce join key,所以只会启用一个reducer,数据量大时会造成性能瓶颈

 

 
  1. // Use only 1 reducer in case of cartesian product

  2. if (reduceKeys.size() == 0) {

  3. numReds = 1;

  4.  
  5. // Cartesian product is not supported in strict mode

  6. if (conf.getVar(HiveConf.ConfVars.HIVEMAPREDMODE).equalsIgnoreCase(

  7. "strict")) {

  8. throw new SemanticException(ErrorMsg.NO_CARTESIAN_PRODUCT.getMsg());

  9. }

  10. }

 

 

2. order by后面不跟limit。order by会强制将reduce number设置成1,不加limit,会将所有数据sink到reduce端来做全排序。

 

 
  1. if (sortExprs == null) {

  2. sortExprs = qb.getParseInfo().getOrderByForClause(dest);

  3. if (sortExprs != null) {

  4. assert numReducers == 1;

  5. // in strict mode, in the presence of order by, limit must be specified

  6. Integer limit = qb.getParseInfo().getDestLimit(dest);

  7. if (conf.getVar(HiveConf.ConfVars.HIVEMAPREDMODE).equalsIgnoreCase(

  8. "strict")

  9. && limit == null) {

  10. throw new SemanticException(generateErrorMessage(sortExprs,

  11. ErrorMsg.NO_LIMIT_WITH_ORDERBY.getMsg()));

  12. }

  13. }

  14. }

 

 

3. 读取的表是partitioned table,但没有指定partition predicate。

注:如果是多级分区表的话,只要出现任何一个就放行

 

 
  1. // If the "strict" mode is on, we have to provide partition pruner for

  2. // each table.

  3. if ("strict".equalsIgnoreCase(HiveConf.getVar(conf,

  4. HiveConf.ConfVars.HIVEMAPREDMODE))) {

  5. if (!hasColumnExpr(prunerExpr)) {

  6. throw new SemanticException(ErrorMsg.NO_PARTITION_PREDICATE

  7. .getMsg("for Alias \"" + alias + "\" Table \""

  8. + tab.getTableName() + "\""));

  9. }

  10. }

 

这三种case在数据量比较大的情况下都会造成生成低效的MR Job,影响执行时间和效率,不过直接抛出exception又感觉太forcefully了。

可以在一些非线上生产环境下的ad-hoc查询端中开启strict mode,比如hiveweb,运营工具。

 

本文链接http://blog.csdn.net/lalaguozhe/article/details/12044181,转载请注明

 

================================================================

1. order by

    Hive中的order by跟传统的sql语言中的order by作用是一样的,会对查询的结果做一次全局排序,所以说,只有hive的sql中制定了order by所有的数据都会到同一个reducer进行处理(不管有多少map,也不管文件有多少的block只会启动一个reducer)。但是对于大量数据这将会消耗很长的时间去执行。
    这里跟传统的sql还有一点区别:如果指定了hive.mapred.mode=strict(默认值是nonstrict),这时就必须指定limit来限制输出条数,原因是:所有的数据都会在同一个reducer端进行,数据量大的情况下可能不能出结果,那么在这样的严格模式下,必须指定输出的条数。
2. sort by

    Hive中指定了sort by,那么在每个reducer端都会做排序,也就是说保证了局部有序(每个reducer出来的数据是有序的,但是不能保证所有的数据是有序的,除非只有一个reducer),好处是:执行了局部排序之后可以为接下去的全局排序提高不少的效率(其实就是做一次归并排序就可以做到全局排序了)。

3. distribute by和sort by一起使用

    ditribute by是控制map的输出在reducer是如何划分的,举个例子,我们有一张表,mid是指这个store所属的商户,money是这个商户的盈利,name是这个store的名字

store:


mid    money    name
AA    15.0    商店1
AA    20.0    商店2
BB    22.0    商店3
CC    44.0    商店4
    执行hive语句:

select mid, money, name from store distribute by mid sort by mid asc, money asc
我们所有的mid相同的数据会被送到同一个reducer去处理,这就是因为指定了distribute by mid,这样的话就可以统计出每个商户中各个商店盈利的排序了(这个肯定是全局有序的,因为相同的商户会放到同一个reducer去处理)。这里需要注意的是distribute by必须要写在sort by之前。
4. cluster by

    cluster by的功能就是distribute by和sort by相结合,如下2个语句是等价的:

    

select mid, money, name from store cluster by mid
select mid, money, name from store distribute by mid sort by mid
    如果需要获得与3中语句一样的效果:
select mid, money, name from store cluster by mid sort by money
    注意被cluster by指定的列只能是降序,不能指定asc和desc


原文:https://blog.csdn.net/jthink_/article/details/38903775 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值