HIVE快速入门教程6-区(Partition)和桶(Bucke
分区
默认情况下,简单的HQL查询会扫描整个表。查询大表时,这会降低性能。可以通过创建分区来解决此问题,这些分区与RDBMS中的分区非常相似。在Hive中,每个分区对应于预定义的分区列,这些分区列映射到HDFS中表的目录中的子目录。当查询表时,只读取表中所需的数据分区(目录),因此查询的I/O和时间大大减少。使用分区是提高Hive性能的一种非常简单有效的方法。
以下是HQL中分区创建的示例:
必须使用ALTER TABLE ADD PARTITION语句将静态分区添加到表中。这里,static表示手动添加分区。
此命令更改表的元数据但不加载数据。如果分区位置中不存在数据,则查询不会返回任何结果。要删除分区元数据,请使用ALTER TABLE ... DROP PARTITION语句。对于外部表,ALTER不会更改数据而是元数据,drop partition不会丢弃分区内的数据。我们可以使用hdfs dfs -rm命令从HDFS中删除外部表的数据。对于内部表,ALTER TABLE ... DROP PARTITION将删除分区和数据。以下是分区表上常见操作的更多示例:
为避免手动添加静态分区,动态分区插入(或多分区插入)旨在动态确定在扫描输入表时应添加和填充哪些分区。
要在分区中填充数据,我们可以使用LOAD或INSERT语句。该语句仅加载指定分区列表中的数据。
虽然分区列映射到目录名而不是数据,但我们可以像在HQL中的常规列一样查询或选择它们以缩小结果集。
静态和动态分区的用例完全不同。静态分区通常用于包含新登陆HDFS的数据的外部表。在这种情况下,它通常使用日期(例如yyyyMMdd)作为分区列。每当新日期的数据到达时,我们将特定于日期的静态分区(通过脚本)添加到表中,然后立即从表中查询新到达的数据。对于动态分区,它通常用于内部表之间的数据转换,其中分区列是从数据本身派生的;见第5章,数据操作。
删除数据不会删除分区信息。
我们不能将新列添加为分区列。从分区表CASCADE和RESTRICT添加/删除列时有两个选项。常用的CASCADE选项将相同的更改级联到表中的所有分区。但是,RESTRICT是默认值,限制列仅更改为表元数据,这意味着更改将仅应用于新分区而不是现有分区:
可以更改现有的分区列数据类型:
根据文件格式,位置,保护和密度更改分区的其他属性
> CREATE TABLE employee_partitioned ( name STRING, work_place ARRAY<STRING>, gender_age STRUCT<gender:STRING,age:INT>, skills_score MAP<STRING,INT>, depart_title MAP<STRING,ARRAY<STRING>>) PARTITIONED BY (year INT, month INT) ROW FORMAT DELIMITED FIELDS TERMINATED BY '|' COLLECTION ITEMS TERMINATED BY ',' MAP KEYS TERMINATED BY ':';
OK
Time taken: 1.07 seconds
hive> DESC employee_partitioned;
OK
name string
work_place array<string>
gender_age struct<gender:string,age:int>
skills_score map<string,int>
depart_title map<string,array<string>>
year int
month int
# Partition Information
# col_name data_type comment
year int
month int
Time taken: 0.246 seconds, Fetched: 12 row(s)
hive> SHOW PARTITIONS employee_partitioned;
OK
Time taken: 0.311 seconds
hive>
> ALTER TABLE employee_partitioned ADD PARTITION (year=2018, month=11) PARTITION (year=2018,month=12);
OK
Time taken: 0.832 seconds
hive> SHOW PARTITIONS employee_partitioned;
OK
year=2018/month=11
year=2018/month=12
Time taken: 0.308 seconds, Fetched: 2 row(s)
hive> ALTER TABLE employee_partitioned DROP IF EXISTS PARTITION (year=2018, month=11);
Dropped the partition year=2018/month=11
OK
Time taken: 1.789 seconds
hive> SHOW PARTITIONS employee_partitioned;
OK
year=2018/month=12
Time taken: 0.312 seconds, Fetched: 1 row(s)
hive> ALTER TABLE employee_partitioned DROP IF EXISTS PARTITION (year=2017);
OK
Time taken: 0.344 seconds
hive> ALTER TABLE employee_partitioned DROP IF EXISTS PARTITION (month=9);
OK
Time taken: 0.321 seconds
hive> ALTER TABLE employee_partitioned PARTITION (year=2018, month=12) RENAME TO PARTITION (year=2018,month=10);
OK
Time taken: 0.904 seconds
hive> SHOW PARTITIONS employee_partitioned;
OK
year=2018/month=10
Time taken: 0.268 seconds, Fetched: 1 row(s)
hive> LOAD DATA INPATH '/user/hduser/employee.txt' OVERWRITE INTO TABLE employee_partitioned PARTITION (year=2018, month=12);
Loading data to table default.employee_partitioned partition (year=2018, month=12)
OK
Time taken: 1.996 seconds
hive> SELECT name, year, month FROM employee_partitioned;
OK
Michael 2018 12
Will 2018 12
Shelley 2018 12
Lucy 2018 12
Time taken: 0.47 seconds, Fetched: 4 row(s)
hive> ALTER TABLE employee_partitioned ADD COLUMNS (work string) CASCADE;
OK
Time taken: 0.745 seconds
hive> ALTER TABLE employee_partitioned PARTITION COLUMN(year string);
OK
Time taken: 0.349 seconds