将一个大表的数据按照业务需要分散存储到多个目录,每个目录称为该表的一个分区。一般来说是按照日期来作为分区的标准。在查询时可以通过where子句来选择查询所需要的分区,这样查询效率会提高很多。
①创建分区表
hive (default)>
create table dept_partition
(
deptno int, --部门编号
dname string, --部门名称
loc string --部门位置
)
partitioned by (day string, hour string)
row format delimited fields terminated by '\t';
查询分区表数据时,可以将分区字段看作表的伪列,可像使用其他字段一样使用分区字段。
| 操作命令 | 作用 |
|---|---|
| desc 表名 | 查看表的信息,分辨是否为分区表 |
| show partition 表名 | 查看所有分区信息 |
| alter 表名 add partition(dt=‘’) | 添加分区,多个分区不用添加分隔符 |
| alter 表名 drop partition(),partiton2 | 删除分区, 多个分区逗号分隔 |
| msck repair table 表名 add/drop/ sync partitions | 没有使用hive load命令上传文件时,用来修复分区,默认是add |
如果一天内的数据量也很大,可以再次将数据按照小时进行分区。适合数据量特别大的时候使用
动态分区是指向分区表insert数据时,被写往的分区不由用户指定,而是由每行数据的最后一个字段的值来动态的决定。使用动态分区,可只用一个insert语句将数据写入多个分区。
hive.exec.dynamic.partition=true;hive.exec.dynamic.partition.mode=nonstrictinsert into table dept_partition_dynamic
partition(loc) -- 动态分区就是指这个值没有写死
select
deptno,
dname,
loc
from dept;
分区提供一个隔离数据和优化查询的便利方式。底层是将数据放到不同目录,但是并非所有数据都可形成合理的分区。分桶是指将同一个文件的数据按照分桶数再划分为更细粒度的不同文件。数据内容是按照对应字段的哈希值对桶数取模来分配的。只在特定情况下效率会更高。
create table stu_buck_sort_part(
id int,
name string
)
partitioned by (day string) -- 分区
clustered by (id) sorted by (id)
into 4 buckets -- 分桶
row format delimited fields terminated by '\t';
分区和分桶的区别:
(1)UDF:一进一出
(2)UDAF:多进一出
(3)UDTF:一进多出
create function my_len as "方法的全类名";如果想创建临时方法,在function前面加上temporary。临时函数可以跨库使用,永久函数需要加上前缀库名后才能跨库使用。using "HDFS路径"存储时选择压缩比的最好的bzip2,计算时选择速度快点压缩算法,目前天选加唯一的就是snappy。
| 文件名 | 特点 |
|---|---|
| textfile | 行式存储 |
| orc | 列式存储, 比较适合列式的查询,符合公司业务需求 |
| Parquet | 列式存储 |
使用orc列式存储时可以将原文件大小缩小到原先的40%,parquet大概是原先的70%。在数据量较大时,orc和parquet进行按列查询时查询速度会比textfile速度更快。
语法:explain query-SQL
将聚合操作从reduce阶段提前到map阶段。
set hive.map.aggr = true. 开启预聚合combiner
可以将该参数关闭,比较两次查询过程的执行时间。该优化对于有数据倾斜的数据有很好的优化效果。
连接键来分。set hive.input.format = hive.ql.io.CombineInputFormathive.merge.mapredfiles, 小文件平均大小小于平均值16M时触发合并。这个配置默认是关闭,如果出现输出时小文件很多时,建议修改配置一下。最优成本优化,hive.cbo.enable = true 默认是开启的。多表连接时,会自动将最小的两个表进行连接,这样处理过程中的IO和写入磁盘负担更小,整体速度更快。
在既有join操作和where操作时,先进行连接操作后再进行过滤计算量会远远大于先进行过滤后再进行连接操作。并且这个顺序变化后的结果是一样的。
hive.optimize.ppd = false ,该参数默认是开启的,设置时需要将cbo同时修改。
| 级别 | 作用 |
|---|---|
| none | 不转换成IO、计数器、过滤操作 |
| minimal | select * 转换,其他不转换 |
| more | 尽量转换成不走MR的操作 |
hive.exec.parallel, 默认是关闭的,有利于提高集群的稳定性,如果需要提高效率,可以开启该参数。
exec.parallel.thread.number=8, 设置最大并行度,如果集群比较小,反而会降低效率。
hive.strict.checks.no.partition.filter=false; 默认是关闭的,查询数据时必须给分区参数,否则报错。日常是开启的,年终是关闭的。年终时需要进行文件的合并操作。
order by 后面必须添加limit n关键字,提高map阶段的shuffle速度,只需要排序前面n条数据。
笛卡尔乘积默认会开启,连接时必须加连接条件。