打赏

06_Hive分桶机制及其作用

1.Clustered By

  对于每一个表(table)或者分区, Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。

Hive也是针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在

哪个桶当中。

  把表(或者分区)组织成桶(Bucket)有两个理由:

  (1)获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体

而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的

实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同

列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。

  (2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一

小部分数据上试运行查询,会带来很多方便。

2.分桶

  分桶是相对分区进行更细粒度的划分,它是相当于MapReduce中的分区,分桶将整个数据按照某列属性值的hash

值进行区分,例如如果根据id属性分为3个桶,就是对id属性值的hash值对3取摸,按照取模结果对数据分桶。如取

模结果为0的数据记录存放到一个文件,取模为1的数据存放到一个文件,取模为2的数据存放到一个文件

1.创建带桶的表:导入的数据已经是被分好桶和排好序的

   

  在分桶之前要执行命令:set hive.enforce.bucketing = true; set mapreduce.job.reduces=4;从而设置分桶

为true,并且reduce数量是分桶的数量个数;

  关键字clustered by 指定分区依据的列名;

  与分区不同的是,分区依据的不是真实数据表文件中的列,而是我们指定的伪列,但是分桶是依据数据表中真实

的列而不是伪列。所以在指定分区依据的列的时候要指定列的类型,因为在数据表文件中不存在这个列,相当于新建

一个列。而分桶依据的是表中已经存在的列,这个列的数据类型显然是已知的,所以不需要指定列的类型

  如上只是说明了表会分桶,具体的分区需要在插入数据时产生。最好的插入数据方式是insert into table;

2.带桶的表中插入select数据(Cluster by(id)):表示根据id分桶并排序

  cluster by和sort by不能放在一起查询

  

  按照上面的分桶结果会在表目录下产生多个文件:/user/hive/warehouse/test_db/t_buk/

  查看文件信息:

  

3.带桶的表中插入select数据(distribute by (id) sort by (id)):

  

  按照上面的分桶结果会在表目录下产生多个文件:/user/hive/warehouse/test_db/t_buk/

  

  如上的的sql查询语句实际上是根据id作为key进行key.hashcode%4产生四个区,即就是用distribute by (id)

来指定分区字段,使用sort by (id)指定排序字段

总结:

  因此,如果分桶和sort字段是同一个时,此时,cluster by = distribute by + sort by

  如果将reduce数量设置为4,使用select * from t_test order by name;就会强制将reduce设置为1,会得到全局结果;

SELECT语法操作:
  SELECT [ALL | DISTINCT] select_expr, select_expr, ... 
  FROM table_reference
  [WHERE where_condition] 
  [GROUP BY col_list [HAVING condition]] 
  [CLUSTER BY col_list 
    | [DISTRIBUTE BY col_list] [SORT BY| ORDER BY col_list] 
  ] 
  [LIMIT number]

注:1order by 会对输入做全局排序,因此只有一个reducer,会导致当输入规模较大时,需要较长的计算时间。
  2、sort by不是全局排序,其在数据进入reducer前完成排序。因此,如果用sort by进行排序,并且设置mapred.reduce.tasks>1
则sort by只保证每个reducer的输出有序,不保证全局有序。   
3distribute by(字段)根据指定的字段将数据分到不同的reducer,且分发算法是hash散列。   4Cluster by(字段) 除了具有Distribute by的功能外,还会对该字段进行排序。   因此,如果分桶和sort字段是同一个时,此时,cluster by = distribute by + sort by 分桶表的作用:最大的作用是用来提高join操作的效率; (思考这个问题:select a.id,a.name,b.addr from a join b on a.id = b.id; 如果a表和b表已经是分桶表,而且分桶的字段是id字段,那么做这个操作的时候就不需要再进行全表笛卡尔积了。但是如果标注了分桶但是实际上数据并没有分桶,那么结果就会出问题。

 

 

 

 

  

 

 

 

 

 

 

 

 

 

 

 

posted @ 2018-07-09 15:19  QueryMarsBo  阅读(1194)  评论(1编辑  收藏  举报