hive优化
一.explain(执行计划)
通过执行计划来调节SQL语句
1.基本语法
EXPLAIN [EXTENDED | DEPENDENCY | AUTHORIZATION] query
2.示例
(1)查看sql语句的执行计划
hive> explain select * from student;
hive> explain select s_id,avg(scores) avgscore from score group by s_id;
--可以看出下面一条语句需要启动mapreduce,mapreduce里面的信息都有展示
(2)查看详细执行计划
hive> explain extended select * from score;
hive> explain extended select s_id,avg(scores) avgscore from score group by s_id;
二.Fetch抓取(默认已开启)
Fetch 抓取是指,Hive 中对某些情况的查询可以不必使用 MapReduce 计算。
例如:SELECT * FROM employees;在这种情况下,Hive 可以简单地读取 employee对应的存储目录下的文件,然后输出查询结果到控制台。
在 hive-default.xml.template 文件中 hive.fetch.task.conversion
默认是more,老版本 hive 默认是 minimal,该属性修改为 more 以后,在全局查找、字段查找、limit 查找等都不走 mapreduce。
<property>
<name>hive.fetch.task.conversion</name>
<value>more</value>
</property>
-
set hive.fetch.task.conversion=none;
后执行查询语句,都会执行mapreduce 程序。
hive (default)> select * from emp; hive (default)> select ename from emp; hive (default)> select ename from emp limit 5;
-
set hive.fetch.task.conversion=more
后执行查询语句,如下查询方式都不会执行 mapreduce 程序。
hive (default)> select * from emp; hive (default)> select ename from emp; hive (default)> select ename from emp limit 5;
三.本地模式
大多数的Hadoop Job是需要Hadoop提供的完整的可扩展性来处理大数据集的。不过,有时 Hive 的输入数据量是非常小的。在这种情况下,为查询触发执行任务时消耗可能会比实际 job 的执行时间要多的多。对于大多数这种情况,Hive可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间可以明显被缩短。
数据量小时可以设置本地模式缩短运行时间
用户可以通过设置 hive.exec.mode.local.auto 的值为 true,来让 Hive 在适当的时候自动启动这个优化。
--开启本地 mr
set hive.exec.mode.local.auto=true;
--设置 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=8;
四.表的优化
1.小表、大表join
将 key 相对分散,并且数据量小的表放在 join 的左边,这样可以有效减少内存溢出错误发生的几率;再进一步,可以使用 Group 让小的维度表(1000 条以下的记录条数)先进内存。在 map 端完成 reduce。
实际测试发现:新版的 hive 已经对小表 JOIN 大表和大表 JOIN 小表进行了优化。小表放在左边和右边已经没有明显区别
--关闭 mapjoin 功能(默认是打开的)
set hive.auto.convert.join = false;
insert overwrite table jointable
select b.id, b.time, b.uid, b.keyword, b.url_rank, b.click_num,
b.click_url
from smalltable s
left join bigtable b
on b.id = s.id;
2.大表jion大表
(1)空key过滤
原因: 有时 join 超时是因为某些 key 对应的数据太多,而相同 key 对应的数据都会发送到相同的 reducer 上,从而导致内存不够。此时我们应该仔细分析这些异常的 key,很多情况下,这些 key 对应的数据是异常数据,我们需要在 SQL 语句中进行过滤。
示例演示:
1)配置历史服务器
- 配置mapred-site.xml
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop101:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>hadoop101:19888</value>
</property>
- 启动历史服务器
mr-jobhistory-daemon.sh start historyserver
- 查看jobhistory
浏览器输入 http://hadoop101:19888 进行访问
2)创建原始数据表,空id表,合并后数据表
create table ori(id bigint, time bigint, uid string, keyword string, url_rank int,
click_num int