hive的查询注意事项以及优化总结 .

一、控制Hive中Map和reduce的数量

Hive中的sql查询会生成执行计划,执行计划以MapReduce的方式执行,那么结合数据和集群的大小,map和reduce的数量就会影响到sql执行的效率。

除了要控制Hive生成的Job的数量,也要控制map和reduce的数量。

1、 map的数量,通常情况下和split的大小有关系,之前写的一篇blog“map和reduce的数量是如何定义的”有描述。

hive中默认的hive.input.format是org.apache.hadoop.hive.ql.io.CombineHiveInputFormat,对于combineHiveInputFormat,它的输入的map数量

由三个配置决定,

mapred.min.split.size.per.node, 一个节点上split的至少的大小

mapred.min.split.size.per.rack 一个交换机下split至少的大小

mapred.max.split.size 一个split最大的大小

它的主要思路是把输入目录下的大文件分成多个map的输入, 并合并小文件, 做为一个map的输入. 具体的原理是下述三步:

a、根据输入目录下的每个文件,如果其长度超过mapred.max.split.size,以block为单位分成多个split(一个split是一个map的输入),每个split的长度都大于mapred.max.split.size, 因为以block为单位, 因此也会大于blockSize, 此文件剩下的长度如果大于mapred.min.split.size.per.node, 则生成一个split, 否则先暂时保留.

b、现在剩下的都是一些长度效短的碎片,把每个rack下碎片合并, 只要长度超过mapred.max.split.size就合并成一个split, 最后如果剩下的碎片比mapred.min.split.size.per.rack大, 就合并成一个split, 否则暂时保留.

c、把不同rack下的碎片合并, 只要长度超过mapred.max.split.size就合并成一个split, 剩下的碎片无论长度, 合并成一个split.

举例: mapred.max.split.size=1000

mapred.min.split.size.per.node=300

mapred.min.split.size.per.rack=100

输入目录下五个文件,rack1下三个文件,长度为2050,1499,10, rack2下两个文件,长度为1010,80. 另外blockSize为500.

经过第一步, 生成五个split: 1000,1000,1000,499,1000. 剩下的碎片为rack1下:50,10; rack2下10:80

由于两个rack下的碎片和都不超过100, 所以经过第二步, split和碎片都没有变化.

第三步,合并四个碎片成一个split, 长度为150.

如果要减少map数量, 可以调大mapred.max.split.size, 否则调小即可.

其特点是: 一个块至多作为一个map的输入,一个文件可能有多个块,一个文件可能因为块多分给做为不同map的输入, 一个map可能处理多个块,可能处理多个文件。

2、 reduce数量

可以在hive运行sql的时,打印出来,如下:

Number of reduce tasks not specified. Estimated from input data size: 1

In order to change the average load for a reducer (in bytes):

set hive.exec.reducers.bytes.per.reducer=<number>

In order to limit the maximum number of reducers:

set hive.exec.reducers.max=<number>

In order to set a constant number of reducers:

set mapred.reduce.tasks=<number>

reduce数量由以下三个参数决定,

mapred.reduce.tasks(强制指定reduce的任务数量)

hive.exec.reducers.bytes.per.reducer(每个reduce任务处理的数据量,默认为1000^3=1G)

hive.exec.reducers.max(每个任务最大的reduce数,默认为999)

计算reducer数的公式很简单N=min( hive.exec.reducers.max ,总输入数据量/ hive.exec.reducers.bytes.per.reducer )

只有一个reduce的场景:

a、没有group by 的汇总

b、order by

c、笛卡尔积

二、join和Group的优化

对于普通的join操作,会在map端根据key的hash值,shuffle到某一个reduce上去,在reduce端做join连接操作,内存中缓存join左边的表,遍历右边的表,一次做join操作。所以在做join操作时候,将数据量多的表放在join的右边。

当数据量比较大,并且key分布不均匀,大量的key都shuffle到一个reduce上了,就出现了数据的倾斜。

对于Group操作,首先在map端聚合,最后在reduce端坐聚合,hive默认是这样的,以下是相关的参数
         · hive.map.aggr = true是否在 Map 端进行聚合,默认为 True
        · hive.groupby.mapaggr.checkinterval = 100000在 Map 端进行聚合操作的条目数目

对于join和Group操作都可能会出现数据倾斜。

以下有几种解决这个问题的常见思路

1、参数hive.groupby.skewindata = true,解决数据倾斜的万能钥匙,查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。

2、where的条件写在join里面,使得减少join的数量(经过map端过滤,只输出复合条件的)

3、mapjoin方式,无reduce操作,在map端做join操作(map端cache小表的全部数据),这种方式下无法执行Full/RIGHT OUTER join操作

4、对于count(distinct)操作,在map端以group by的字段和count的字段联合作为key,如果有大量相同的key,那么会存在数据倾斜的问题
      5、数据的倾斜还包括,大量的join连接key为空的情况,空的key都hash到一个reduce上去了,解决这个问题,最好把空的key和非空的key做区分
         空的key不做join操作。

当然有的hive操作,不存在数据倾斜的问题,比如数据聚合类的操作,像sum、count,因为已经在map端做了聚合操作了,到reduce端的数据相对少一些,所以不存在这个问题。

四、小文件的合并

大量的小文件导致文件数目过多,给HDFS带来压力,对hive处理的效率影响比较大,可以合并map和reduce产生的文件

· hive.merge.mapfiles = true是否和并 Map 输出文件,默认为 True
          · hive.merge.mapredfiles = false是否合并 Reduce 输出文件,默认为 False
         · hive.merge.size.per.task = 256*1000*1000合并文件的大小

五、in/exists(not)

通过left semi join 实现 in操作,一个限制就是join右边的表只能出现在join条件中

六、分区裁剪

通过在条件中指定分区,来限制数据扫描的范围,可以极大提高查询的效率

七、排序

order by 排序,只存在一个reduce,这样效率比较低。

可以用sort by操作,通常结合distribute by使用做reduce分区键

摘自  http://blog.csdn.net/joe_007/article/details/8987422

hive的查询注意事项以及优化总结 .,布布扣,bubuko.com

时间: 2024-10-21 22:37:40

hive的查询注意事项以及优化总结 .的相关文章

hive select查询语句底层实现的某些细微差别

最近,由于工作的需要,学习了基于Hadoop的一个数据仓库工具hive.遇到并解决了一些问题,但是有个select语句的细微差别值得注意. 首先来看两条hql语句: SELECT * FROM MY_TABLE where dt=2014031205 limit 10     SELECT ID,NAME,GENDER,USERNAME,PASSWORD,ISVALID FROM MY_TABLE where dt=2014031205 limit 10 理论上,上述两条hql查询语句的查询结果

hive 子查询特别分析

转自: http://blog.csdn.net/ls3648098/article/details/9630357 Hive只支持在FROM子句中使用子查询,子查询必须有名字,并且列必须唯一:SELECT ... FROM(subquery) name ... 确认下是否一定要求列必须唯一? 建表语句: create table  tb_in_base ( id  bigint, devid bigint, devname string ) partitioned by (job_time b

Sql动态查询拼接字符串的优化

Sql动态查询拼接字符串的优化 最原始的 直接写:string sql="select * from TestTables where 1=1";... 这样的代码效率很低的,这样影响了数据库的索引引用如下所示:private void TestOneMethod()        {             string querySql = "select * from TestTables where 1=1";            if (hasOneCo

建立HBase的集群和HDInsight在Hadoop中使用Hive来查询它们

在本教程中,您将学习如何创建和查询HDInsight使用HiveHadoop的HBase的表.下列步骤描述:?如何使用提供在Azure门户的HBase的集群.?如何启用和使用RDP访问HBase的外壳,并使用HBase的外壳创建HBase的示例表,添加行,然后列出表中的行.?如何创建一个Hive表映射到一个现有的HBase的表,使用HiveQL查询数据在HBase的表.?如何使用Microsoft HBase的REST客户端库.NET创建一个新的HBase的表,列出您帐户中的HBase的表,以及

hive表查询中文显示乱码

hive在查询表信息时,中文显示乱码,数字或者url显现null问题解决思路. 1.确定create hive表时指定的row format delimited fields terminated by 'xxx'中"xxx"格式是否和原始导入表的data的行列分隔格式一致,如不一致,则会出现select结果中数字或者url显现null等问题,所以需先统一格式. 2.Windows使用的GB2312编码,大多数Linux系统支持的是UTF-8编码,而在Windows远程登陆时使用的是本

hive 高级查询1

hadoop hive 高级查询 select基础 1.0 一般查询 1)select * from table_name 2)select * from table_name where name='....' limit 1; 1.1cte和嵌套查询 1)with t as(select....) select * from t; 2)select * from(select....) a;(a一定要添加) 1.2列匹配正则表达式 在添加数据前:SET hive.support.quoted

hive 高级查询

hadoop hive 高级查询 Hive聚合运算 - Group by (基本内置聚合函数)nmax, min, count, sum, avg 1)Hive基本内置聚合函数与group by 一起使用 2)支持按位置编号分组 set hive.groupby.orderby.position.alias=true; select name,sum(score) from table_name group by name;——>使用表达式 Hive聚合运算-hiving 1)对group by

MySQL常见注意事项及优化

MySQL常见注意事项 模糊查询 like 默认是对name字段建立了索引 注意:在使用模糊查询的时候,当% 在第一个字母的位置的时候,这个时候索引是无法被使用的.但是% 在其他的位置的时候,索引是可以被使用的. ? # select * from tableName where name like "%zhangsan"; ?可以使用到索引啊? 不可以. 分析:因为是不确定查询,在表中任何一行记录都有可能满足查询条件. ? #select * from tableName where

Hive高级查询(group by、 order by、 join等)

查询操作 group by. order by. join . distribute by. sort by. clusrer by. union all 底层的实现 mapreduce 常见的聚合操作 count计数 count(*) 所有值不全为NULL时,加1操作 count(1) 不管有没有值,只要有这条记录,值就加1 count(col) col列里面的值为null,值不会加1,这个列里面的值不为NULL,才加1 sum求和 sum(可转成数字的值) 返回bigint avg求平均值