- 创建表时可以同时为表创建一个或者多个分区,我们在加载数据时为期指定具体的 分区,查询数据时可以指定具体的分区从而提高效率。
- 分区表是把分区当成目录的,分区实际上是将表文件分成多个有标记的小文件以方便查询。
在Hive Select查询中,一般会扫描整个表内容(HDFS上文件的内容),会消耗很多时间做没必要的工作。分区表指的是在创建表时,指定partition的分区空间。
使用场景:
庞大的数据集可能需要耗费大量的时间去处理。在许多场景下,可以通过分区或切片的方法减少每一次扫描总数据量,这种做法可以显著地改善性能。
数据会依照单个或多个列进行分区,通常按照时间、地域或者是商业维度进行分区。比如vido表,分区的依据可以是电影的种类和评级,另外,按照拍摄时间划分可能会得到更一致的结果。为了达到性能表现的一致性,对不同列的划分应该让数据尽可能均匀分布。最好的情况下,分区的划分条件总是能够对应where语句的部分查询条件。
Hive的分区使用HDFS的子目录功能实现。每一个子目录包含了分区对应的列名和每一列的值。但是由于HDFS并不支持大量的子目录,这也给分区的使用带来了限制。我们有必要对表中的分区数量进行预估,从而避免因为分区数量过大带来一系列问题。
Hive查询通常使用分区的列作为查询条件。这样的做法可以指定MapReduce任务在HDFS中指定的子目录下完成扫描的工作。HDFS的文件目录结构可以像索引一样高效利用。
1.分区表是将大的表文件划分成多个小文件以利于查询,但是如果数据分布不均衡,也会影响查询效率。
2.桶表可以对数据进行哈希取模,目的是让数据能够均匀的分布在表的各个文件中。
3.物理上,每个桶就是表和分区目录里的一个文件,一个作业产生桶和Reduce任务个数据相同。
使用场景:
1.桶表专门用于抽样查询,不是用来存储数据的表,在需要抽样查询时,在创建和使用桶表。
在使用桶表之间,必须要开启桶。
hive (default)> set hive.enforce.bucketing; #查看是否开启
默认是:false
hive.enforce.bucketing=false
hive (default)> set hive.enforce.bucketing=true; #开启分桶
默认:false;设置为true之后,mr运行时会根据bucket的个数自动分配reduce task个数。
(用户也可以通过mapred.reduce.tasks自己设置reduce任务个数,但分桶时不推荐使用)
注意:一次作业产生的桶(文件数量)应该和reduce task个数一致。
hive 内部表和外部表的区别?
- 内部表:建表时会在 hdfs 创建一个表的存储目录,增加分区的时候,会将数据复制到此location下,删除数据的时候,将表的数据和元数据一起删除。
- 外部表:一般会建立分区,增加分区的时候不会将数据移到此表的 location下,删除数据的时候,只删除了表的元数据信息,表的数据不会删除。
寄语专区: