http://lxw1234.com/archives/2015/07/413.htm
類似於Oracle的分析表,Hive中也提供了分析表和分區的功能,通過自動和手動分析Hive表,將Hive表的一些統計信息存儲到元數據中。
表和分區的統計信息主要包括:行數、文件數、原始數據大小、所占存儲大小、最后一次操作時間等;
1 新表的統計信息
對於一個新創建的表,默認情況下,如果通過INSERT OVERWRITE的方式插入數據,那么Hive會自動將該表或分區的統計信息更新到元數據。
有一個參數來控制是否自動統計,hive.stats.autogather,默認為true.
舉例來說:
先創建表lxw1234:
CREATE TABLE lxw1234 ( id STRING, name STRING ) stored AS textfile;
在元數據表TABLE_PARAMS中,會有一條記錄,記錄了該表上次DDL的時間,
該表中的TBL_ID對應TBLS表中的TBL_ID.
關於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方式覆蓋該表數據,那么統計信息將會更新。
2 新分區的統計信息
對於INSERT OVERWRITE方式新增的分區,統計信息同新創建的表,只不過在元數據中存放的表不一樣。
CREATE TABLE lxw1234 ( id STRING, name STRING ) PARTITIONED BY (day STRING);
創建之后,在分區的元數據中還沒有任何該表的信息:
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
3 已存在表或分區的統計信息
對於一個已經存在的表、分區或者外部表,則需要通過ANALYZE命令去手動分析表或分區的統計信息。
- 外部表
CREATE EXTERNAL TABLE lxw1234 ( id STRING, name STRING ) stored AS textfile location 'hdfs://namenode/tmp/lxw1234.com/';
創建之后該表的元數據:
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的方式增加一個分區,道理上其實和外部表沒什么區別;
- CREATE TABLE lxw1234 (
- id STRING,
- name STRING
- ) PARTITIONED BY (day STRING);
- ALTER TABLE lxw1234 ADD PARTITION (day = '2015-07-15')
- location 'hdfs://namenode/tmp/lxw1234.com/';
查看元數據:
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 | |
沒問題了,已經將行數和原始大小統計進來。
