[一起学Hive]之十五-分析Hive表和分区的统计信息(Statistics)

本文介绍了Hive如何自动和手动收集表及分区的统计信息,包括行数、文件数、数据大小等,并展示了如何通过HQL命令查看这些信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

类似于Oracle的分析表,Hive中也提供了分析表和分区的功能,通过自动和手动分析Hive表,将Hive表的一些统计信息存储到元数据中。

表和分区的统计信息主要包括:行数、文件数、原始数据大小、所占存储大小、最后一次操作时间等;

14.1 新表的统计信息

对于一个新创建的表,默认情况下,如果通过INSERT OVERWRITE的方式插入数据,那么Hive会自动将该表或分区的统计信息更新到元数据。

有一个参数来控制是否自动统计,hive.stats.autogather,默认为true.

举例来说:

先创建表lxw1234:

 
  1. CREATE TABLE lxw1234 (
  2. id STRING,
  3. name STRING
  4. ) stored AS textfile;
  5.  

在元数据表TABLE_PARAMS中,会有一条记录,记录了该表上次DDL的时间,

该表中的TBL_ID对应TBLS表中的TBL_ID.

关于Hive元数据结构的详细介绍,可参考前一章:

[一起学Hive]之十四-Hive的元数据表结构详解

SELECT  *  FROM  TABLE_PARAMS  WHERE  tbl_id = 45857

 

TBL_ID PARAM_KEY PARAM_VALUE
45857 transient_lastDdlTime 1436916981

 

接下来通过INSERT OVERWRITE向表lxw1234中插入数据:

INSERT overwrite TABLE lxw1234 SELECT pt,pcid FROM lxw1;

其实在hive-cli中执行HQL之后,会打印出统计信息:

Table default.lxw1234 stats:

[numFiles=1, numRows=11067, totalSize=376278, rawDataSize=365211]

再查看元数据:

SELECT  *  FROM  TABLE_PARAMS  WHERE  tbl_id = 45857

TBL_ID PARAM_KEY PARAM_VALUE
45857 transient_lastDdlTime 1436917459
45857 numFiles 1
45857 numRows 11067
45857 rawDataSize 365211
45857 totalSize 376278
45857 COLUMN_STATS_ACCURATE true
       

 

这里的rawDataSize是指原始数据的大小,totalSize是指占用HDFS存储空间大小。

如果再次使用INSERT OVERWRITE方式覆盖该表数据,那么统计信息将会更新。

 

14.2 新分区的统计信息

对于INSERT OVERWRITE方式新增的分区,统计信息同新创建的表,只不过在元数据中存放的表不一样。

 
  1. CREATE TABLE lxw1234 (
  2. id STRING,
  3. name STRING
  4. ) PARTITIONED BY (day STRING);
  5.  

创建之后,在分区的元数据中还没有任何该表的信息:

SELECT * FROM `PARTITIONS` WHERE tbl_id = 45858

 

插入数据到一个新的分区:

INSERT overwrite TABLE lxw1234 PARTITION (day = ‘2015-07-15′)

SELECT pt,pcid

FROM lxw1;

执行打印出的统计信息:

Loading data to table default.lxw1234 partition (day=2015-07-15)

Partition default.lxw1234{day=2015-07-15} stats:

[numFiles=1, numRows=11067, totalSize=376278, rawDataSize=365211]

 

再查看元数据:

SELECT * FROM `PARTITIONS` WHERE tbl_id = 45858

 

PART_ID CREATE_TIME LAST_ACCESS_TIME PART_NAME SD_ID TBL_ID
56806 1436918167 0 day=2015-07-15 98259 45858

 

SELECT * FROM PARTITION_PARAMS WHERE PART_ID = 56806

PART_ID PARAM_KEY PARAM_VALUE
56806 transient_lastDdlTime 1436918167
56806 numFiles 1
56806 numRows 11067
56806 rawDataSize 365211
56806 totalSize 376278
56806 COLUMN_STATS_ACCURATE true
       

 

与分区统计信息相关的元数据表为

PARTITIONS、PARTITION_PARAMS

 

14.3 已存在表或分区的统计信息

对于一个已经存在的表、分区或者外部表,则需要通过ANALYZE命令去手动分析表或分区的统计信息。

  • 外部表
 
  1. CREATE EXTERNAL TABLE lxw1234 (
  2. id STRING,
  3. name STRING
  4. ) stored AS textfile
  5. location 'hdfs://namenode/tmp/lxw1234.com/';
  6.  

创建之后该表的元数据:

SELECT * FROM TABLE_PARAMS WHERE tbl_id = 45859

TBL_ID PARAM_KEY PARAM_VALUE
45859 transient_lastDdlTime 1436918758
45859 numFiles 0
45859 numRows -1
45859 rawDataSize -1
45859 totalSize 0
45859 COLUMN_STATS_ACCURATE false
45859 EXTERNAL true
       

 

使用命令分析表lxw1234的统计信息:

ANALYZE TABLE lxw1234 COMPUTE STATISTICS;

该命令也会启动MapReduce去执行,执行之后打印:

Table default.lxw1234 stats:

[numFiles=0, numRows=11067, totalSize=0, rawDataSize=365211]

 

查看元数据:

SELECT * FROM TABLE_PARAMS WHERE tbl_id = 45859

 

TBL_ID PARAM_KEY PARAM_VALUE
45859 transient_lastDdlTime 1436918995
45859 numFiles 0
45859 numRows 11067
45859 rawDataSize 365211
45859 totalSize 0
45859 COLUMN_STATS_ACCURATE true
45859 EXTERNAL true
       

 

对于外部表,并没有统计文件数和总大小,估计是统计了该表默认路径下的文件数和大小了。(外部表在创建的时候,同时也会在默认路径下创建一个空目录,比如:hdfs://namenode/user/hive/warehouse/default.db/lxw1234)

 

  • 分区

如果通过ALTER TABLE ADD PARTITION的方式增加一个分区,道理上其实和外部表没什么区别;

 

 
  1. CREATE TABLE lxw1234 (
  2. id STRING,
  3. name STRING
  4. ) PARTITIONED BY (day STRING);
  5.  
  6.  
  7. ALTER TABLE lxw1234 ADD PARTITION (day = '2015-07-15')
  8. location 'hdfs://namenode/tmp/lxw1234.com/';
  9.  

 

查看元数据:

SELECT * FROM PARTITION_PARAMS WHERE PART_ID = 56807

 

PART_ID PARAM_KEY PARAM_VALUE
56807 transient_lastDdlTime 1436919355
56807 numFiles 20
56807 numRows -1
56807 rawDataSize -1
56807 totalSize 376278
56807 COLUMN_STATS_ACCURATE false
       

 

很欣慰,通过这种方式增加分区时候,Hive已经将分区所对应的路径中的文件数和总大小统计到元数据中。

再使用命令分析该分区:

ANALYZE TABLE lxw1234 PARTITION (day = ‘2015-07-15′)

COMPUTE STATISTICS;

Partition default.lxw1234{day=2015-07-15} stats:

[numFiles=20, numRows=11067, totalSize=376278, rawDataSize=365211]

 

再查看元数据:

SELECT * FROM PARTITION_PARAMS WHERE PART_ID = 56807

 

PART_ID PARAM_KEY PARAM_VALUE
56807 transient_lastDdlTime 1436919604
56807 numFiles 20
56807 numRows 11067
56807 rawDataSize 365211
56807 totalSize 376278
56807 COLUMN_STATS_ACCURATE true

 

没问题了,已经将行数和原始大小统计进来。

<think>嗯,用户想知道Hive分区是否可以动态维护以及如何实现。我需要先回忆一下Hive的动态分区相关知识。记得Hive支持动态分区,这样在插入数据时,系统可以根据指定的字段自动创建分区,而无需手动指定每个分区。 首先,动态分区的配置参数是什么来着?对了,需要设置hive.exec.dynamic.partition为true,还有hive.exec.dynamic.partition.mode设为nonstrict,这样允许所有分区都是动态的。用户可能遇到配置的问题,所以需要详细说明这些参数。 然后,动态分区的语法是怎样的?在插入数据时,使用INSERT...SELECT语句,并在PARTITION中指定分区字段,顺序要SELECT中的字段对应。例如,如果按年分区,SELECT最后两个字段应该是yearmonth,这样Hive会自动根据这些值创建分区。 还要注意性能问题,比如动态分区数量太多可能导致资源消耗大,需要调整参数如hive.exec.max.dynamic.partitions。另外,动态分区通常多级分区结合使用,比如年、月两级分区,这样管理更方便,查询效率也更高。 用户可能还关心动态分区静态分区的区别,以及使用场景。动态分区适合分区值不确定的情况,而静态分区需要明确指定值。应用场景比如日志数据按天分区,或者电商订单按地区时间分区。 需要确保回答结构清晰,分步骤说明配置方法、语法示例、注意事项等。同时,根据提供的引用内容,引用相关配置案例,比如引用13提到的配置参数,引用4中的多级分区示例,以及引用2中Flink SQL的动态分区应用。 最后,生成相关问题,帮助用户进一步了解动态分区的优化、与静态分区的对比以及实际应用案例。这些应该覆盖用户可能感兴趣的扩展内容。</think>Hive的动态分区维护方法可分为以下步骤实现: ### 一、动态分区配置方法 1. **启用动态分区功能** 需要先配置以下参数: ```sql SET hive.exec.dynamic.partition = true; -- 开启动态分区 SET hive.exec.dynamic.partition.mode = nonstrict; -- 允许全动态分区[^1][^3] ``` 2. **优化参数(可选)** 根据数据量调整以下参数: ```sql SET hive.exec.max.dynamic.partitions = 1000; -- 单个查询允许的最大动态分区数 SET hive.exec.max.dynamic.partitions.pernode = 100; -- 单节点允许的最大动态分区数 ``` ### 二、动态分区语法实现 通过`INSERT...SELECT`语句自动生成分区: ```sql INSERT INTO TABLE target_table PARTITION (partition_col1, partition_col2) SELECT col1, col2, ..., partition_col1_value, -- 动态分区字段值 partition_col2_value -- 必须作为SELECT的最后几列 FROM source_table; ``` *示例*:将订单按`year``month`动态分区 ```sql INSERT INTO orders_partitioned PARTITION (year, month) SELECT order_id, amount, region, year(order_date), -- 动态分区字段1 month(order_date) -- 动态分区字段2 FROM raw_orders; ``` 此时Hive会自动根据`year(order_date)``month(order_date)`的值创建分区目录(如`/year=2023/month=10/`)[^4] ### 三、动态分区的核心特性 | 特性 | 说明 | |---------------------|----------------------------------------------------------------------| | **自动分区创建** | 根据数据内容自动生成分区目录 | | **多级分区支持** | 最多支持3级分区(如`年/月/日`)[^4] | | **数据重分布** | 相同分区字段值的数据自动归集到同一分区 | ### 四、使用注意事项 1. **字段顺序要求** 动态分区字段必须作为`SELECT`语句的最后几列,且顺序与`PARTITION()`中声明的一致 2. **性能优化建议** - 避免单个查询产生过多分区(超过`hive.exec.max.dynamic.partitions`会导致任务失败) - 动态分区字段建议选择低基数列(如时间、地区等离散值) 3. **数据倾斜预防** 监控分区数据量分布,可通过`ANALYZE TABLE ... COMPUTE STATISTICS`分析分区信息 ### 五、典型应用场景 1. 日志分析系统:按`日期+小时`动态分区存储访问日志[^2] 2. 电商订单分析:按`地区+订单月份`动态分区 3. 物联网数据存储:按`设备类型+采集日期`动态分区
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值