1.分区

2.分桶

分区主要是文件夹的拆分。分桶则是对文件的拆分。因此其实分区和分桶并不冲突。分桶可以在分区的基础上进一步根据分桶字段hash取模,打散分发到各个不同的桶来完成分桶。分桶主要有以下场景:

2.1join

如果另外一个表也按照同样的规则分成了一个个小文件。两个表join的时候,就不必要扫描整个表,只需要匹配相同分桶的数据即可,从而提升效率。在数据量足够大的情况下,分桶比分区有更高的查询效率。

2.2数据采样

在真实的大数据分析过程中,由于数据量较大就可以使用分桶来进行数据采样。采样使用的是一个具有代表性的查询结果而不是全部结果。

2.3常见命令

  1. 创建分桶表
  2. create table stu_buck(id int, name string)
  3. clustered by(id)
  4. into 4 buckets
  5. row format delimited fields terminated by '\t';
  6. !!!!!注意分桶的数据需要走MR才能导入,因此可以使用tmp表作为中间表
  7. 抽样
  8. select * from stu_buck tablesample(bucket 1 out of 4 on id);
  9. 注意:
  10. y必须是tablebucket数的倍数或者因子
  11. x表示从第几个bucket开始抽取
  12. x的值必须小于等于y的值,否则
  13. 例如:
  14. 例如,tablebucket数为4tablesample(bucket 1 out of 2),表示总共抽取(4/2=)2bucket的数据
  15. 抽取第1(x)个和第3(x+y)个bucket的数据。
  16. 优化配置:
  17. 1.启用桶表:set hive.enforce.bucketing=true;
  18. 2.限制对桶表进行load操作: set hive.strict.checks.bucketing = true;

3.Join优化

3.1MapJoin

就像名字写的那样MapJoin的实质其实就是在Map阶段完成join工作而不是到reduce段完成。MapJoin的应用场景时其中的一个表数据特表大,另外的一个表数据量特别小(数据倾斜)。运行时Map阶段会将小表的数据放到每个MapTast内存中,完成Join工作,这样就大大的减少了mr过程中的shuffer的数据量。从而到达提升效率的目的。需要支持的时从0.7以后hive默认支持mapjoin。另外默认要求(n-1)*table的数据量应该<20Mb通过设置(set hive.auto.convert.join.noconditionaltask.size=512000000)设置为52MB。该场景使用1.大小表关联2.不等连接

3.2Bucket Map Join

中型表和大表进行join是如果也想使用MapJoin但是内存有放不下的话,可以使用BuecketMapJoin来处理。其方法是两个join表在join key上都做hash bucket,并且把你打算复制的那个(相对)小表的bucket数设置为大表的倍数。这样MapTask时依然将相对小表的数据copy到每个Map中,Map Join时小表中的每一组bucket就会加载到HashTable中,与对应的大表的hash bucket 做局部join,这样每次只需要加载局部的hashtable就可以了

  1. 1)必须开启bucket map join支持: set hive.optimize.bucketmapjoin = true;
  2. 2)一个表的bucket数是另一个表bucket数的整数倍
  3. 3)bucket == join
  4. 4)必须是应用在map join的场景中
  5. 5)表必须是分桶表

3.3SMB(Sort merge Bucket) Map join

  1. 1)必须开启bucket map join支持: set hive.optimize.bucketmapjoin = true;
  2. 2)一个表的bucket数等于另一个表bucket
  3. 3 bucket == join == sort
  4. 4 必须是应用在bucket map join的场景中
  5. 5) 表必须是分桶表
  6. -- 启动桶表
  7. set hive.enforce.bucketing=true;
  8. -- 保证必须进行强制排序操作(建表时和写入数据都要保证)
  9. set hive.enforce.sorting=true;
  10. -- 开启 bucket map join
  11. set hive.optimize.bucketmapjoin = true;
  12. -- 开启 SMB join
  13. set hive.auto.convert.sortmerge.join=true;
  14. set hive.auto.convert.sortmerge.join.noconditionaltask=true;
  15. -- 是否自动尝试使用SMB join 连接 可以直接在CM中配置
  16. set hive.optimize.bucketmapjoin.sortedmerge = true;

4.数据格式:
建表推荐使用ORC格式,使用列式存储
ODS层数据推荐使用ZLIB,其他层推荐使用Snappy
set hive.exec.orc.compression.strategy=COMPRESSION;

4.索引

Hive支持索引,但是Hive的索引与关系型数据库中的索引并不相同,比如,Hive不支持主键或者外键。
Hive索引可以建立在表中的某些列上,以提升一些操作的效率,例如减少MapReduce任务中需要读取的数据块的数量。
在可以预见到分区数据非常庞大的情况下,分桶和索引常常是优于分区的。而分桶由于SMB Join对关联键要求严格,所以并不是总能生效。

4.1Hive原始索引

Hive的索引目的是提高Hive表指定列的查询速度。
没有索引时,类似’WHERE tab1.col1 = 10’ 的查询,Hive会加载整张表或分区,然后处理所有的rows,但是如果在字段col1上面存在索引时,那么只会加载和处理文件的一部分。
在每次建立、更新数据后,Hive索引不会自动更新,需要手动进行更新(重建索引以构建索引表),会触发一个mr job。
Hive索引使用过程繁杂,而且性能一般,在Hive3.0中已被删除,在工作环境中不推荐优先使用,在分区数量过多或查询字段不是分区字段时,索引可以作为补充方案同时使用。推荐使用ORC文件格式的索引类型进行查询。

4.2Row Group Index

一个ORC文件包含一个或多个stripes(groups of row data),每个stripe中包含了每个column的min/max值的索引数据,当查询中有<,>,=的操作时,会根据min/max值,跳过扫描不包含的stripes。
而其中为每个stripe建立的包含min/max值的索引,就称为Row Group Index行组索引,也叫min-max Index大小对比索引,或者Storage Index。
在建立ORC格式表时,指定表参数’orc.create.index’=’true’之后,便会建立Row Group Index,需要注意的是,为了使Row Group Index有效利用,向表中加载数据时,必须对需要使用索引的字段进行排序,否则,min/max会失去意义。另外,这种索引主要用于数值型字段的查询过滤优化上。
设置hive.optimize.index.filter为true,并重启hive

4.3Bloom Filter Index

在建表时候,通过表参数”orc.bloom.filter.columns”=”pcid”来指定为那些字段建立BloomFilter索引,这样,在生成数据的时候,会在每个stripe中,为该字段建立BloomFilter的数据结构,当查询条件中包含对该字段的=号过滤时候,先从BloomFilter中获取以下是否包含该值,如果不包含,则跳过该stripe。
只有在数据量较大时,使用索引才能带来性能优势。

5Hive并行操作

5.1Hive编译查询限制

Hive默认同时只能编译一段HiveQL,并上锁。
将hive.driver.parallel.compilation设置为true,各个会话可以同时编译查询,提高团队工作效率。否则如果在UDF中执行了一段HiveQL,或者多个用户同时使用的话, 就会锁住。
修改hive.driver.parallel.compilation.global.limit的值,0或负值为无限制,可根据团队人员和硬件进行修改,以保证同时编译查询。

5.2Hive不同阶段任务并行执行

  1. Hive会将一个查询转化为一个或多个阶段,包括:MapReduce阶段、抽样阶段、合并阶段、limit阶段等。默认情况下,一次只执行一个阶段。不过,如果某些阶段不是互相依赖,是可以并行执行的。
  2. set hive.exec.parallel=true,可以开启并发执行,默认为false
  3. set hive.exec.parallel.thread.number=16; //同一个sql允许的最大并行度,默认为8。

6.其他设置

6.1 Hive小文件合并

  1. 此部分设置,要根据硬件内存来进行调整,个人电脑配置较低,不建议修改。
  2. hive.merge.mapfiles
  3. 是否开启合并Map端小文件,在Map-only的任务结束时合并小文件,true是打开。
  4. hive.merge.mapredfiles
  5. 是否开启合并Reduce端小文件,在map-reduce作业结束时合并小文件。true是打开。
  6. hive.merge.size.per.task
  7. 合并后MR输出文件的大小,默认为256M
  8. hive.merge.smallfiles.avgsize
  9. 当输出文件的平均大小小于此设置值时,启动一个独立的map-reduce任务进行文件merge,默认值为16M

6.2矢量化查询

hive的默认查询执行引擎一次处理一行,而矢量化查询执行是一种hive特性,目的是按照每批1024行读取数据,并且一次性对整个记录整合(而不是对单条记录)应用操作,注意:要使用矢量化查询执行,就必须以ORC格式存储数据。

set hive.vectorized.execution.enabled=true;

6.3读取零拷贝

ORC可以使用新的HDFS缓存API和ZeroCopy读取器来避免在扫描文件时将额外的数据复制到内存中。

set hive.exec.orc.zerocopy=true;

6.4未整理的优化

!!!!!!!!!!!!!!!!!!!!!联优化器—报名用户看板
  1. 4.2.3.1.1 关联优化器