0
点赞
收藏
分享

微信扫一扫

Hive的分区与排序

寒羽鹿 2天前 阅读 1

一、Hive分区

1.引入:

        在大数据中,最常见的一种思想就是分治,我们可以把大的文件切割划分成一个个的小的文件,这样每次操作一个个小的文件就会很容易了,同样的道理,在hive当中也是支持这种思想的,就是我们可以把大的数据,按照每天或者每小时切分成一个个小的文件,这样去操作小的文件就会容易很多了。

2.优点:

避免全局搜索,减少数据扫描工作量,提高了查询效率。

3.静态分区(SP)

借助于物理的文件夹分区,实现快速检索的目的

一般对于查询比较频繁的列设置为分区列

需要手动插入或加载数据进行分区

图示:

4.动态分区(DP)

  • 静态分区与动态分区的主要区别在于静态分区是手动指定,而动态分区是通过数据来进行判断。

  • 详细来说,静态分区的列是在编译时期通过用户传递来决定的;动态分区只有在SQL执行时才能决定

开启动态分区首先要在hive会话中设置如下的参数:

动态分区案例: 动态插入学生年级班级信息

原始表数据:

将原始数据表的查询结果作为分区结果加载到分区表中:

insert overwrite table t_student_d partition (grade,clazz)  select * from t_student_e;

5.分区表操作

举例:

(1)全表扫描,不推荐,效率低

select count(*) from st_student_d;

(2)使用where条件进行分区裁剪,避免了全表扫描,效率高

select count(*) from st_student_d where grade = 1;

(3)也可以在where条件中使用非等值判断

select count(*) from t_student_d where grade<3 and grade>=1;

(4)查看分区

show partitions t_student_d;

(5)添加分区

alter table t_student_d add partition (grade=6);

(6)删除分区

alter table t_student_d drop partition (grade=5);

2.1 业务场景

二、Hive分桶

1.概述与使用场景

概述:在Hive中,分桶是一种用于提高查询性能的技术,通过将数据集分成更小的、可管理的部分来实现。分桶是通过对表的某一列进行哈希来实现的,Hive会根据分桶列的值来确定数据应该放入哪个桶。

使用场景:当我们的分区之后,最后的文件还是很大怎么办,就引入了分桶的概念。将这个比较大的文件再分成若干个小文件进行存储,我们再去查询的时候,在这个小范围的文件中查询就会快很多。对于hive中的每一张表、分区都可以进一步的进行分桶。当然,分桶不是说将文件随机进行切分存储,而是有规律的进行存储。

2.数据分桶原理

Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中

  • bucket num = hash_function(bucketing_column) mod num_buckets

  • 列的值做哈希取余 决定数据应该存储到哪个桶

3.数据分桶优势

4.分桶案例:

(1)首先我们需要开启分桶的支持

(2)创建一个普通的表

(3)数据准备(id,name,age)

(4创建分桶表

(5)将查询的数据insert到表psn_bucket中

5.分桶和分区的区别

分区和分桶的区别在于其提供的性能优化方向不同。分区适用于数据快速访问特定的数据范围,而分桶适用于对于数据JOIN操作的效率提升。

分区之后会产生分区文件夹,数据会存储在问价夹下的文件中,分桶不会产生文件夹,数据直接存储在分桶之后的文件中。简而言之,分区是对数据进行划分,而分桶是对文件进行划分。

三、Java连接hive(Hive JDBC)

1.启动hiveserver2

    hiveserver2 &

2.新建maven项目并添加两个依赖

3.编写JDBC代码

import java.sql.*;

public class HiveJDBC {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Class.forName("org.apache.hive.jdbc.HiveDriver");
        Connection conn = DriverManager.getConnection("jdbc:hive2://master:10000/bigdata29");
        Statement stat = conn.createStatement();
        ResultSet rs = stat.executeQuery("select * from students limit 10");
        while (rs.next()) {
            int id = rs.getInt(1);
            String name = rs.getString(2);
            int age = rs.getInt(3);
            String gender = rs.getString(4);
            String clazz = rs.getString(5);
            System.out.println(id + "," + name + "," + age + "," + gender + "," + clazz);
        }
        rs.close();
        stat.close();
        conn.close();
    }
}

四、Hive排序

1.全局排序(order by

  • order by 会对输入做全局排序,因此只有一个reducer,会导致当输入规模较大时,需要较长的计算时间

  • 使用 order by子句排序 :ASC(ascend)升序(默认)| DESC(descend)降序

  • order by放在select语句的结尾

  • 语法:select * from 表名 order by 字段名1[,别名2...];

2.局部排序(对reduce内部做排序)

  • sort by 不是全局排序,其在数据进入reducer前完成排序

  • 如果用sort by进行排序,并且设置mapred.reduce.tasks大于1,则sort by 只保证每个reducer的输出有序,不保证全局有序。asc,desc都可以。

3.分区排序(指定分区方式局部排序)

  • distribute by(字段)根据指定的字段将数据分到不同的reducer,且分发算法是hash散列。

    类似MR中partition,进行分区,结合sort by使用。(注意:distribute by 要在sort by之前)

  • 指定分区排序,相同字段的数据可以分到同一分区,在此分区下是有序的

步骤:

4.分区并排序(指定分区方式局部排序)

  • cluster by = distribute by + sort by 只能默认升序,不能使用倒序

  • 当distribute by 字段1 sort by 字段2 ,当字段1,字段2是相同字段时,可用cluster by 。分区后再排序,会比distribute by id sort by id要快

语法:

四种排序图解:

举报

相关推荐

0 条评论