算法
例如:select * from score;sql
在这种状况下,Hive能够简单地读取employee对应的存储目录下的文件,而后输出查询结果到控制台 apache
在hive-default.xml.template文件中 ==hive.fetch.task.conversion默认是more==,老版本hive默认是minimal,该属性修改成more之后,app
在全局查找、字段查找、limit查找等都不走mapreduce。负载均衡
案例实操jvm
把 hive.fetch.task.conversion设置成==none==分布式
set hive.fetch.task.conversion=none; select * from score; select s_id from score; select s_id from score limit 3;
ide
set hive.fetch.task.conversion=more; select * from score; select s_id from score; select s_id from score limit 3;
oop
Hive能够经过本地模式在单台机器上处理任务。对于小数据集,执行时间能够明显被缩短。性能
--开启本地模式,并执行查询语句 set hive.exec.mode.local.auto=true; //开启本地mr --设置local mr的最大输入数据量,当输入数据量小于这个值时采用local mr的方式, --默认为134217728,即128M set hive.exec.mode.local.auto.inputbytes.max=50000000; --设置local mr的最大输入文件个数,当输入文件个数小于这个值时采用local mr的方式, --默认为4 set hive.exec.mode.local.auto.input.files.max=5; --执行查询的sql语句 select * from student cluster by s_id;
--关闭本地运行模式 set hive.exec.mode.local.auto=false; select * from student cluster by s_id;
有时join超时是由于某些key对应的数据太多,而相同key对应的数据都会发送到相同的reducer上,从而致使内存不够。
--开启MapJoin参数设置 set hive.auto.convert.join = true;
并非全部的聚合操做都须要在Reduce端完成,不少聚合操做均可以先在Map端进行部分聚合,最后在Reduce端得出最终结果。
--是否在Map端进行聚合,默认为True set hive.map.aggr = true; --在Map端进行聚合操做的条目数目 set hive.groupby.mapaggr.checkinterval = 100000; --有数据倾斜的时候进行负载均衡(默认是false) set hive.groupby.skewindata = true; 当选项设定为 true,生成的查询计划会有两个MR Job。
第一个MR Job中,Map的输出结果会随机分布到Reduce中,每一个Reduce作部分聚合操做,
并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不一样的Reduce中,从而达到负载均衡的目的;
第二个MR Job再根据预处理的数据结果按照Group By Key分布到Reduce中(这个过程能够保证相同的Group By Key被分布到同一个Reduce中),最后完成最终的聚合操做。
列剪裁
只获取须要的列的数据,减小数据输入。
分区裁剪
分区在hive实质上是目录,分区裁剪能够方便直接地过滤掉大部分数据。
尽可能使用分区过滤
把一个sql语句中没有相互依赖的阶段并行去运行。提升集群资源利用率
--开启并行执行 set hive.exec.parallel=true; --同一个sql容许最大并行度,默认为8。 set hive.exec.parallel.thread.number=16;
经过设置属性hive.mapred.mode值为默认是非严格模式nonstrict 。开启严格模式须要修改hive.mapred.mode值为strict
--设置非严格模式(默认) set hive.mapred.mode=nonstrict; --设置严格模式 set hive.mapred.mode=strict;
(1)对于分区表,除非where语句中含有分区字段过滤条件来限制范围,不然不容许执行
--设置严格模式下 执行sql语句报错; 非严格模式下是能够的 select * from order_partition; 异常信息:Error: Error while compiling statement: FAILED: SemanticException [Error 10041]: No partition predicate found for Alias "order_partition" Table "order_partition"
(2)对于使用了order by语句的查询,要求必须使用limit语句
--设置严格模式下 执行sql语句报错; 非严格模式下是能够的 select * from order_partition where month='2019-03' order by order_price; 异常信息:Error: Error while compiling statement: FAILED: SemanticException 1:61 In strict mode, if ORDER BY is specified, LIMIT must also be specified. Error encountered near token 'order_price'
(3)限制笛卡尔积的查询,严格模式下,避免出现笛卡尔积的查询
<property> <name>mapreduce.job.jvm.numtasks</name> <value>10</value> <description>How many tasks to run per jvm. If set to -1, there is no limit. </description> </property>
咱们也能够在hive当中经过
set mapred.job.reuse.jvm.num.tasks=10;
<property> <name>mapreduce.map.speculative</name> <value>true</value> <description>If true, then multiple instances of some map tasks may be executed in parallel.</description> </property> <property> <name>mapreduce.reduce.speculative</name> <value>true</value> <description>If true, then multiple instances of some reduce tasks may be executed in parallel.</description> </property>
不过hive自己也提供了配置项来控制reduce-side的推测执行:
<property> <name>hive.mapred.reduce.tasks.speculative.execution</name> <value>true</value> <description>Whether speculative execution for reducers should be turned on. </description> </property>
关于调优这些推测执行变量,还很难给一个具体的建议。若是用户对于运行时的误差很是敏感的话,那么能够将这些功能关闭掉。若是用户由于输入数据量很大而须要执行长时间的map或者Reduce task的话,那么启动推测执行形成的浪费是很是巨大大。
Hive表中间数据压缩
#设置为true为激活中间数据压缩功能,默认是false,没有开启 set hive.exec.compress.intermediate=true; #设置中间数据的压缩算法 set mapred.map.output.compression.codec= org.apache.hadoop.io.compress.SnappyCodec;
Hive表最终输出结果压缩
set hive.exec.compress.output=true; set mapred.output.compression.codec = org.apache.hadoop.io.compress.SnappyCodec;
more