赞
踩
分区在主要是在Reduce端的操作,Map端为切片
本质上就是对hdfs上的文件分目录存放,避免全表扫描
一般是按天分区
create table dept_partition(
deptno int, dname string, loc string
)
partitioned by (day string)
row format delimited fields terminated by '\t';
分区字段(day)不能是已经存在的字段,可以把分区字段看成是表的伪列
dept_20200401.log
10 ACCOUNTING 1700
20 RESEARCH 1800
dept_20200402.log
30 SALES 1900
40 OPERATIONS 1700
dept_20200403.log
50 TEST 2000
60 DEV 1900
show partitions dept_partition;
创建单个分区
alter table dept_partition add partition(day='20200404') ;
同时创建多个分区(分区之间不能有逗号)
alter table dept_partition add partition(day='20200405') partition(day='20200406');
删除单个分区
alter table dept_partition drop partition (day='20200406');
同时删除多个分区(分区之间必须有逗号)
alter table dept_partition drop partition (day='20200404'), partition(day='20200405');
desc formatted dept_partition;
全表扫描
select * from dept_partition where deptno = 10;
走分区优化方式
select * from dept_partition where day = 20200401;
create table dept_partition2(
deptno int, dname string, loc string
)
partitioned by (day string, hour string)
row format delimited fields terminated by '\t';
当一天的数据也很大时,可以先按天分区,再按小时做第二次分区
hive -e "load data local inpath '/opt/module/hive/datas/dept_20200401.log' into table dept_partition2 partition(day='20200401', hour='12');"
上传数据到hdfs
hive -e "dfs -mkdir -p /user/hive/warehouse/db_hive1.db/dept_partition2/day=20200401/hour=13;"
hive -e "dfs -put /opt/module/hive/datas/dept_20200401.log /user/hive/warehouse/db_hive1.db/dept_partition2/day=20200401/hour=13;"
查询数据(查询不到刚上传的数据)
解决方式
方式1(处理已经上传到hdfs上的数据)
执行修复命令
msck repair table dept_partition2;
再次查询数据
方式2(处理已经上传到hdfs上的数据)
上传数据后添加分区
alter table dept_partition2 add partition(day='20200401',hour='14');
再次查询数据
方式3(处理未上传到hdfs上的数据)
创建文件夹后load数据到分区
hive -e "load data local inpath '/opt/module/hive/datas/dept_20200401.log' into table db_hive1.dept_partition2 partition(day='20200401',hour='15');"
跑这个任务最好分发数据,因为load数据这个任务,可能会在任何一台服务器上执行
再次查询数据
1)将已经存在的表数据,按照loc进行动态分区
select deptno, dname, loc from dept;
2)建表
create table dept_partition_dy(id int, name string) partitioned by (loc int) row format delimited fields terminated by '\t';
3)设置动态分区
设置非严格模式
set hive.exec.dynamic.partition.mode = nonstrict;
插入数据
insert into table dept_partition_dy partition(loc) select deptno, dname, loc from dept;
create table stu_buck(id int, name string)
clustered by(id)
into 4 buckets
row format delimited fields terminated by '\t';
根据id字段的哈希值拆分成4个桶
1001 ss1 1002 ss2 1003 ss3 1004 ss4 1005 ss5 1006 ss6 1007 ss7 1008 ss8 1009 ss9 1010 ss10 1011 ss11 1012 ss12 1013 ss13 1014 ss14 1015 ss15 1016 ss16
load data inpath '/student.txt' into table stu_buck;
1、对于生产上环境的hive来说,如果数据量巨大,其最容易想到的优化思路之一就是分区,或者分桶。
一般而言,将数据分区会更常见,但不管是分区还是分桶,其本质作用是将数据进行【打散】并分布存储,它最大的优势在于可以有效过滤掉跟查询条件无关的数据。
2、但是分区的特点是数量不固定,这个是根据你的分区字段的值来的,相同值的在同一个分区,而且可以用多级分区。
而分桶不同,它的数量需要你提前设置,是固定的,且只能根据某一个字段来进行分桶。
3、分桶是默认是根据hash算法来确定那个数据写入到哪个桶中,因此当你的where条件有分桶字段的时候是可以 定位到哪个桶的。
所以分桶有2个好处,一个是让数据进一步打散,也就是让单个map数据量变小,再一个就是提高查询效率,当然前提是分桶字段作为筛选条件。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。