hive的查询注意事项以及优化总结 .
Hive是将符合SQL语法的字符串解析生成可以在Hadoop上执行的MapReduce的工具。使用Hive尽量按照分布式计算的一些特点来设计sql,和传统关系型数据库有区别,
所以需要去掉原有关系型数据库下开发的一些固有思维。
基本原则:
1:尽量尽早地过滤数据,减少每个阶段的数据量,对于分区表要加分区,同时只选择需要使用到的字段
select ... from A
join B
on A.key = B.key
where A.userid>10
and B.userid<10
and A.dt='20120417'
and B.dt='20120417';
应该改写为:
select .... from (select .... from A
where dt='201200417'
and userid>10
) a
join ( select .... from B
where dt='201200417'
and userid < 10
) b
on a.key = b.key;
2、对历史库的计算经验 (这项是说根据不同的使用目的优化使用方法)
历史库计算和使用,分区
3:尽量原子化操作,尽量避免一个SQL包含复杂逻辑
可以使用中间表来完成复杂的逻辑
4 jion操作 小表要注意放在join的左边(目前TCL里面很多都小表放在join的右边)。
否则会引起磁盘和内存的大量消耗
5:如果union all的部分个数大于2,或者每个union部分数据量大,应该拆成多个insert into 语句,实际测试过程中,执行时间能提升50%
insert overwite table tablename partition (dt= ....)
select ..... from (
select ... from A
union all
select ... from B
union all
select ... from C
) R
where ...;
可以改写为:
insert into table tablename partition (dt= ....)
select .... from A
WHERE ...;
insert into table tablename partition (dt= ....)
select .... from B
WHERE ...;
insert into table tablename partition (dt= ....)
select .... from C
WHERE ...;
5:写SQL要先了解数据本身的特点,如果有join ,group操作的话,要注意是否会有数据倾斜
如果出现数据倾斜,应当做如下处理:
set hive.exec.reducers.max=200;
set mapred.reduce.tasks= 200;---增大Reduce个数
set hive.groupby.mapaggr.checkinterval=100000 ;--这个是group的键对应的记录条数超过这个值则会进行分拆,值根据具体数据量设置
set hive.groupby.skewindata=true; --如果是group by过程出现倾斜 应该设置为true
set hive.skewjoin.key=100000; --这个是join的键对应的记录条数超过这个值则会进行分拆,值根据具体数据量设置
set hive.optimize.skewjoin=true;--如果是join 过程出现倾斜 应该设置为true
(1) 启动一次job尽可能的多做事情,一个job能完成的事情,不要两个job来做
通常来说前面的任务启动可以稍带一起做的事情就一起做了,以便后续的多个任务重用,与此紧密相连的是模型设计,好的模型特别重要.
(2) 合理设置reduce个数
reduce个数过少没有真正发挥hadoop并行计算的威力,但reduce个数过多,会造成大量小文件问题,数据量、资源情况只有自己最清楚,找到个折衷点,
(3) 使用hive.exec.parallel参数控制在同一个sql中的不同的job是否可以同时运行,提高作业的并发
2、让服务器尽量少做事情,走最优的路径,以资源消耗最少为目标
比如:
(1) 注意join的使用
若其中有一个表很小使用map join,否则使用普通的reduce join,注意hive会将join前面的表数据装载内存,所以较小的一个表在较大的表之前,减少内存资源的消耗
(2)注意小文件的问题
在hive里有两种比较常见的处理办法
第一是使用Combinefileinputformat,将多个小文件打包作为一个整体的inputsplit,减少map任务数
set mapred.max.split.size=256000000;
set mapred.min.split.size.per.node=256000000
set Mapred.min.split.size.per.rack=256000000
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
第二是设置hive参数,将额外启动一个MR Job打包小文件
hive.merge.mapredfiles = false 是否合并 Reduce 输出文件,默认为 False
hive.merge.size.per.task = 256*1000*1000 合并文件的大小
(3)注意数据倾斜
在hive里比较常用的处理办法
第一通过hive.groupby.skewindata=true控制生成两个MR Job,第一个MR Job Map的输出结果随机分配到reduce做次预汇总,减少某些key值条数过多某些key条数过小造成的数据倾斜问题
第二通过hive.map.aggr = true(默认为true)在Map端做combiner,假如map各条数据基本上不一样, 聚合没什么意义,做combiner反而画蛇添足,hive里也考虑的比较周到通过参数hive.groupby.mapaggr.checkinterval = 100000 (默认)hive.map.aggr.hash.min.reduction=0.5(默认),预先取100000条数据聚合,如果聚合后的条数/100000>0.5,则不再聚合
(4)善用multi insert,union all
multi insert适合基于同一个源表按照不同逻辑不同粒度处理插入不同表的场景,做到只需要扫描源表一次,job个数不变,减少源表扫描次数
union all用好,可减少表的扫描次数,减少job的个数,通常预先按不同逻辑不同条件生成的查询union all后,再统一group by计算,不同表的union all相当于multiple inputs,同一个表的union all,相当map一次输出多条
(5) 参数设置的调优
集群参数种类繁多,举个例子比如
可针对特定job设置特定参数,比如jvm重用,reduce copy线程数量设置(适合map较快,输出量较大)
如果任务数多且小,比如在一分钟之内完成,减少task数量以减少任务初始化的消耗。可以通过配置JVM重用选项减少task的消耗
-----------------------------------------------------------
一、控制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的时,打印出来,如下:
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 )
对于Group操作,首先在map端聚合,最后在reduce端坐聚合,hive默认是这样的,以下是相关的参数
· hive.map.aggr = true是否在 Map 端进行聚合,默认为 True
· hive.groupby.mapaggr.checkinterval = 100000在 Map 端进行聚合操作的条目数目
5、数据的倾斜还包括,大量的join连接key为空的情况,空的key都hash到一个reduce上去了,解决这个问题,最好把空的key和非空的key做区分
空的key不做join操作。
· hive.merge.mapredfiles = false是否合并 Reduce 输出文件,默认为 False
· hive.merge.size.per.task = 256*1000*1000合并文件的大小
hive的查询注意事项以及优化总结 .的更多相关文章
- HIVE中查询FAILED: Error in metadata: javax.jdo.JDOFatalDataStoreException: Communications link failure
有一天早上到公司用hive中查询数据,发现报错不能连接.通过检查发现mysql服务器没有启动,开启mysql服务器后查询正常.
- Sql动态查询拼接字符串的优化
Sql动态查询拼接字符串的优化 最原始的 直接写:string sql="select * from TestTables where 1=1";... 这样的代码效率很低的,这样 ...
- Hive sql 查询数据库查询 top-n
数据库查询*分组排序取top n要求:按照课程分组,查找每个课程最高的两个成绩. 数据文件如下: 第一列no为学号,第二列course为课程,第三列score为分数 mysql> select ...
- Hive 的查询结果直接导入到 MySQL 中的方法
步骤一: hive> add jar /setup/hive/lib/mysql-connector-java-5.1.25-bin.jar; hive> add jar /usr/lib ...
- hive表查询中文显示乱码
hive在查询表信息时,中文显示乱码,数字或者url显现null问题解决思路. 1.确定create hive表时指定的row format delimited fields terminated b ...
- 【mysql】mysql统计查询count的效率优化问题
mysql统计查询count的效率优化问题 涉及到一个问题 就是 mysql的二级索引的问题,聚簇索引和非聚簇索引 引申地址:https://www.cnblogs.com/sxdcgaq8080/p ...
- mysql 5.7 innodb count count(*) count(1) 大数据 查询慢 耗时多 优化
原文:mysql 5.7 innodb count count(*) count(1) 大数据 查询慢 耗时多 优化 问题描述 mysql 5.7 innodb 引擎 使用以下几种方法进行统计效率差不 ...
- Hive通过查询语句向表中插入数据注意事项
最近在学习使用Hive(版本0.13.1)的过程中,发现了一些坑,它们或许是Hive提倡的比关系数据库更加自由的体现(同时引来一些问题),或许是一些bug.总而言之,这些都需要使用Hive的开发人员额 ...
- MySQL常见注意事项及优化
MySQL常见注意事项 模糊查询 like 默认是对name字段建立了索引 注意:在使用模糊查询的时候,当% 在第一个字母的位置的时候,这个时候索引是无法被使用的.但是% 在其他的位置的时候,索引是可 ...
随机推荐
- MySQL Performance Tuning: Tips, Scripts and Tools
With MySQL, common configuration mistakes can cause serious performance problems. In fact, if you mi ...
- nw 系统托盘的添加方式,以及ajax失效问题
1.nw 系统托盘的添加方式 /** ------------------------------------------------------------ 最小化托盘 -------------- ...
- WCF异常相关
1.端口没打开 解决办法: services.msc 启动Net.Tcp Port Sharing Service 2.由于访问被拒,服务终结点未能侦听 URI“net.tcp://localhost ...
- CentOS7安装OpenStack(Rocky版)-03.安装Glance镜像服务组件(控制节点)
上篇文章分享了keystone的安装配置,本文接着分享openstack的镜像服务glance. --------------- 完美的分割线 ---------------- 3.0.glance概 ...
- asp.net excel 操作
/// <summary> /// 数据操作 /// </summary> /// <param name="fileName"></pa ...
- Cocos2d-x 2.2.3 使用NDK配置编译环境
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/wwj_748/article/details/30072379 Cocos2d-x 2.2.3 使用 ...
- Linux下安装xampp和bugfree
1.BugFree简介 1.1 BugFree的来源 BugFree是借鉴微软的研发流程和Bug管理理念,使用PHP+MySQL独立写出的一个Bug管理系统.简单实用.免费并且开放源代码(遵循GNU ...
- IdentityHashMap 与 HashMap 的区别
IdentityHashMap 中的 key 允许重复 IdentityHashMap 使用的是 == 比较 key 的值(比较内存地址),而 HashMap 使用的是 equals()(比较存储值) ...
- position 属性值:relative 与 absolute 区别
absolute 能让元素 inline-block 化: 例如一个div标签默认宽度是100%显示的,但是一旦被absolute属性缠上,则100%默认宽度就会变成自适应内部元素的宽度. float ...
- spring4 知识点
1 bean的 创建 1,直接在配置文件里面写一个带有@Bean注解的方法(返回值就是那个bena对象),(name等于 方法名) 2,使用 FactoryBean 接口(三个方法分别是创建,类型,单 ...