简介
hive的表在hdfs上对应一个文件目录,当使用hive进行select查询操作时,会对这个目录下的所有文件进行全表的扫描,其实这样的查询时很浪费性能的,这样就引入了partiton(分区)和bucket(桶)的概念。
hive的分区和桶都是把hive的表进行分块的操作,但是partiton是粗粒度的划分,而bucket是细粒度的划分,从而提高查询的效率
分区表
分区表指的是创建表时,指定partition的分区空间
语法:
Partitioned by(par_col par_type)
partitioned by(字段名 字段类型)
动态分区和静态分区
静态分区是指用来分区的值是固定的,例如按天进行分区,这样的分区就是固定的,因为日期是固定的。动态分区与之相反,用来分区的值是不固定的,由输入的数据来决定,这样的分区表就可以称为动态分区。
关于动态分区和静态分区的博文:
http://blog.csdn.net/baishuo491/article/details/39857885
动态分区和静态分区是由 hive.exec.dynamic.partition来决定的,由set命令来制定,默认是开启的
默认情况下模式设定hive.exec.dynamic.partition.mode为strict(严格)的,一般我们将其更改为nonstrict。在strict模式下,动态分区表必须设置至少一个分区字段为静态分区字段.而在nonstrice模式下,可以指定任意个动态分区字段
每一个分区值都会形成一个具体的分区目录,例如用日期作为表test的分区字段,就会在test这个表的目录下生成多个以日期明明的目录
- 分区字段为伪字段,不能与表定义字段重名;
分区表的关键字
- partiton by 指定分区字段
- Clustered By 除了具有distrubuted by的功能外还兼备sort by的特点,所以最终的结果是每个reduce处理的数据不重叠,且每个Reduce内的数据是排序,从而达到全局有序的结果
- Sort By 保证同一个Reduce中的数据可以按定字段排序,使用sort by可以指定执行的reduce个数,sort by默认是升序的排序方式。
- Distributed By 按照指定字段将数据划分到不同的输出Reduce中,这样可以保证每个Reduce所处理的数据是没有排序的
http://blog.csdn.net/andrewgb/article/details/47359673
桶表(Bucketed Sorted Tables)
把表(或者分区)组织成桶有如下两个原因
- 获得更高的查询处理效率
- 使(sampling)更加高效
倾斜表(SkewedTables)
用户在建立表的时候如果知道这张表的某个字段在某值上会出现数据的倾斜,那么可以建立倾斜表来解决这个问题
建表语法
CREATE TABLE USER(userid int,username string)
Skewed by(userid) on(null)[Stored as directories]
作用及原理
Skew table只是通过将倾斜特别严重的列分开存储为不同的文件,每个倾斜之指定为一个目录或者一个文件,因此查询的时候,可以通过过滤倾斜来避免数据倾斜的问题,减少进行全表的扫描,节省性能.但是如果在使用倾斜表时,未设置过滤,仍会执行全表的扫描
临时表(Temporary Tables)
只能在当前会话中可见的表称为临时表,和关系型数据中的临时表类似
建表语法
CREATE TEMPORARY TABLE TEST_TEMP(ID INT)
介绍
我们在hive中执行上述建表语句,再使用show tables;可以看到已经存在test_temp这张表.我们再打开一个终端,执行show tables,发现是没有这张表的.这说明临时表只在当前的session中才是可见的.
我们在hive中去执行desc formatted test_temp,我们发现临时表的存储路径是不同于其他表的,他存储在hdfs上的tmp文件夹下,而我们正常的表是会存储在user目录下的数据仓库中
- 如果创建历史表时,创建了一个与已存在表名相同的临时表,则在当前会话中,所有对该表的使用都是指向临时表(若要使用已存在的表,则需要对临时表进行更名或者删除的操作)
局限性
建议仅做简单实验时使用
- 不支持分区字段
- 不支持建立索引