Hive基础重点知识+优化(个人总结)
Hive基础
Hive简介:(1)hql相对于MR程序没有复杂的代码,上手简单,会写sql的同学,hql也不在话下,区别不是很大。(2)Hive作为数据仓库使用,工作中常用的就是数据的查询(select)和加载(insert)
1、 内部表和外部表的区别:内部表删除元数据和真实数据,外部表只删除元数据
2、 一般创建内部表的时候,不指定location的位置,一般放在默认的hive仓库路 径:/user/hive/warehouse/;外部表最好指定location
3、存储格式:(1)、textfile:默认存储格式,行存储,磁盘和数据解析开销大,压缩的text文件 hive无法进行合并和拆分。(2)、sequencefile:二进制键值对行存储,可分割,压缩,一般选择block压缩,优势是文件和hadoop api mapfile是相互兼容的。(3)、rcfile:存储方式:数据按行分块,每块按照列存储,压缩快,快速列存取,读记录尽量涉及到的block最少 ,读取需要的列只需要读取每个row group的头部定义,读取全量数据的操作性能可能比sequencefile没有明显的优势。(4)、orc:存储方式:按行分块,按列存储,压缩快,快速列存取,效率的rcfile高,改良版。(5)、自定义格式:可以通过实现inputformat来定义输入输出格式
4、常用语句(我就不分类了):(1)、查询表结构: desc 表名; (2)、显示库:show databases; (3)、选择库:use 库名; (4)、显示库下所有表:show tables; (5)、查询创表语句:show create table 表名; (6)、查询 select 字段 from 表名 (join 表名 on 表连接条件) where 条件 group by 字段 having 条件 order by 字段 limit 数字 (7)、加载:load data local inpath "/.txt" into table 表名 (8)、插入数据:insert (override) table 表名 partition(分区字段) select ......
5、cluster by 和sort by 不能连用,distribute by age sort by id ; 分桶;left semi join 只显示左面的表 半连接效率高
6、经典的窗口函数:select * from(select a.movietype,a.movieid,b.avgrate,row_number() over(distribute by movietype sort by avgrate desc) as rn from result_8_1 a join result_8_2 b on (a.movieid=b.movieid)) ab where ab.rn<=5;
7、窗口函数(三种):row_number() over(distribute by sort by ) 12345 ;rank() over() 12335 ; dense_rank() over() 12334
8、执行顺序:from->where ->group by ->having-> select->distinct-> 别名-> order by ->
9、hql中 select中的字段必须要在group中存在,否则报错(其实就算不报错,这语句也没什么意义)
10、hive -i 脚本 初始化命令; hive -e "sql"; hive -f 脚本 -hiveconf hive.exec.mode.local.auto=true ; hive -S 只输出结果
11、group by 和 join 容易数据倾斜,数据倾斜的原因: shuffle 阶段 造成reduce 分配不均,数据倾斜直接结果:效率低,闲置资源多,任务错误指数上升
12、常用的日期函数,字符串处理函数,自行搜索,网上很多,这个工作中使用特别多
13、一些常用函数:concat、concat_ws、instr、substr ,聚合函数max、count等等
14、写脚本时可能和python 连用,需要加 add file *.py SELECT TRANSFORM(tmp.*)
USING 'python *.py'
Hive优化
1、多表连接join 会缓存左边的表 小表写前面
2、笛卡尔积优化:构造随机连接,有多少不同连接,就复制多少份小表缓存到内存中,在和大表join,只要内存够就可以进行mapjoin
3、set hive.exec.mode.local.auto=true; 本地模式
set hive.merge.mapfiles = true ## 在 map only 的任务结束时合并小文件
set hive.merge.mapredfiles = false ## true 时在 MapReduce 的任务结束时合并小文件
set hive.merge.size.per.task = 256000000 ## 合并文件的大小
set mapred.max.split.size=256000000; ## 每个 Map 最大分割大小
set mapred.min.split.size.per.node=1; ## 一个节点上 split 的最少值
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;s## 执行 Map前合并小文件
设置maptask数量
long splitSize = Math.max(minSize, Math.min(maxSize, blockSize))输入的分片大小(取中)
1 、 减少 MapTask 数是通过 合并小文件来实现 ,这一点主要是针对数据源
2 、 增加 MapTask 数可以通过控制上一个 job 的 reduceTask 个数set
set mapred.job.reuse.jvm.num.tasks=5 需要重用jvm,JVM的启动时间会变成一个比较大的消耗
设置reduceTask 的 数量
1、hive.exec.reducers.bytes.per.reducer(默认为 256000000)
2、hive.exec.reducers.max(默认为 1009)
3、mapreduce.job.reduces=-1(设置一个常量 reducetask 数量)
依据 Hadoop 的经验,可以将参数 2 设定为 0.95*( 集群中 datanode 个数)
数据倾斜join优化
set hive.skewjoin.key=100000; // 这个是 join 的键对应的记录条数超过这个值则会进行分拆,值根据具体数据量设置
set hive.optimize.skewjoin=true; // 如果是 join 过程出现倾斜应该设置为 true
group by 优化 (MapReduce 的 combiner 组件)
set hive.map.aggr = true 是否在 Map 端进行聚合,默认为 True
set hive.groupby.mapaggr.checkinterval = 100000 在 Map 端进行聚合操作的条目数目
set hive.groupby.skewindata = true策略就是把 MR 任务拆分成两个:第一个先做预汇总,第二个再做 最终 汇总
并行化
set hive.exec.parallel=true;
set hive.exec.parallel.thread.number=8; // 同一个 sql允许并行任务的最大任务数
压缩
set hive.exec.compress.output=true // 默认值是 false,不压缩
set hive.exec.compress.intermediate=true // 默认值是 false,为 true 时 MR 设置的压缩才启用