网站链接: element-ui dtcms
当前位置: 首页 > 技术博文  > 技术博文

Hive 分区 分桶

2021/6/25 19:06:28 人评论

Hive 分区 && 分桶 分区 1. 作用 为什么会有分区? ​ 表的数据量越来越大,hive 在查询时通常会全表扫描,效率低。所以引入分区技术,提高查询的效率; 使用分区列的值作为目录,进行存放数据&#…

Hive 分区 && 分桶

分区

1. 作用

为什么会有分区?

​ 表的数据量越来越大,hive 在查询时通常会全表扫描,效率低。所以引入分区技术,提高查询的效率;

使用分区列的值作为目录,进行存放数据;这样在存储时,使用分区列进行过滤,只要扫描对应目录下的数据,提高查询的效率。

使用:PARTIONED BY(col_name data_type)

2. 分类

  1. 静态分区

    • 分区列的值,在新增分区和加载分区数据时,必须指定分区名。
  2. 动态分区

    • 分区列的值,非确定,在导入数据的时候自动判断。

    动态分区的相关设置:

    hive.exec.dynamic.partition=true :是否允许动态分区
    hive.exec.dynamic.partition.mode=strict :分区模式设置
    strict:最少需要有一个是静态分区
    	-- 严格模式下会阻止一下操作  为了阻止用户不小心提交恶意hql
                (1)、对分区表查询,where中过滤字段不是分区字段。
                (2)、笛卡尔积join查询,join查询语句,不带on条件 或者 where条件。
                (3)、对order by查询,有order by的查询不带limit语句。
    nostrict:可以全部是动态分区
    hive.exec.max.dynamic.partitions=1000 :允许动态分区的最大数量
    hive.exec.max.dynamic.partitions.pernode =100 :单个节点上的mapper/reducer允许创建的最大分区
    

注意:

  1. 分区列是一个或者多个伪列,在表的数据文件中并不存储分区列的信息和数据
  2. 默认模式下,不允许主分区列是动态分区。

分桶

为什么需要分桶?

  • 单个分区或者表中的数据量越来越大,当分区不能更细粒的划分数据时,所以会采用分桶技术将数据更细粒度的划分和管理
  • 意义:
    • 1、为了保存分桶查询结果的分桶结构(数据已经按照分桶字段进行了hash散列)
    • 2、分桶表数据进行抽样和JOIN时可以提高MR程序效率

1. 原理

分桶则是指定分桶表的某一列,让该列数据按照 哈希取模 的方式随机、均匀地分发到各个桶文件中。因为分桶操作需要根据某一列具体数据来进行哈希取模操作,故指定的分桶列必须基于表中的某一列(字段)。因为分桶改变了数据的存储方式,它会把哈希取模相同或者在某一区间的数据行放在同一个桶文件中。如此一来便可提高查询效率,如:我们要对两张在同一列上进行了分桶操作的表进行JOIN操作的时候,只需要对保存相同列值的桶进行JOIN操作即可。同时分桶也能让取样(Sampling)更高效。

2. 作用

  1. 方便抽样

  2. 提高 join 查询效率

  3. 分桶数据的导入

    1. 先创建一个分桶的空表

    2. 再建立一个临时表 将数据添加到临时表内

    3. 通过查询 insert 将数据导入到分桶表中

      方法一:打开enforce bucketing开关。

      ​ SET hive.enforce.bucketing=true; ①

      ​ INSERT (INTO|OVERWRITE) TABLE <bucketed_table> SELECT <select_statement>
      ​ [SORT BY <sort_key> [ASC|DESC], [<sort_key> [ASC|DESC], …]]; ②

      insert overwrite table buc3
      select uid,uname,uage from buc_temp
      cluster by (uid);
      
      insert overwrite table buc3
      select uid,uname,uage from buc_temp
      distribute by (uid) sort by (uid asc);
      
      insert overwrite table buc3
      select uid,uname,uage from buc_temp
      distribute by (uid) sort by (uid desc);
      
      insert overwrite table buc3
      select uid,uname,uage from buc_temp
      distribute by (uid) sort by (uage desc);
      
      

      方法二:将reducer个数设置为目标表的桶数,并在 SELECT 语句中用 DISTRIBUTE BY <bucket_key>对查询结果按目标表的分桶键分进reducer中。

    4. 总结

      1. 定义:
        clustered by (uid) – 指定分桶的字段
        sorted by (uid desc) – 指定数据的排序规则,表示预期的数据就是以这里设置的字段以及排序规则来进行存储

      2. 导数据
        cluster by (uid) – 指定getPartition以哪个字段来进行hash散列,并且排序字段也是指定的字段,默认以正序进行排序

        distribute by(uid) – 指定getPartition以哪个字段来进行hash散列

        sort by(uid asc) – 指定排序字段,以及排序规则
        –更灵活的方式,这种数据获取方式可以分别指定getPartition的字段和sort的字段

        cluster by (uid)与distribute by(uid) sort by (uid asc)结果是一样的so

      3. order by && sorted by

        • sorted by 局部排序,保证每个reduce上有序,如果只有一个 reduce,那么和order by 一样
        • order by 是全局排序,只有一个 reduce,如果数据量大的话,那么 reduce 就成为了单点,速度很慢
      4. distribute by与group by 的区别

        • 都是按key值划分数据 都使用reduce操作唯一不同的是,distribute by只是单纯的分散数据,distribute by col – 按照col列把数据分散到不同的reduce。而group by把相同key的数据聚集到一起,后续必须是聚合操作。

相关资讯

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?