列级前 K 个统计信息

本文档是Hive 统计的补充。它描述了支持为 Hive 表收集列级别的前 K 个值(请参见HIVE-3421)。

Scope

除了分区统计信息之外,还可以为 Hive 表估计列级别的前 K 个值。
如果用户未指定skew,则最偏斜的列的名称和前 K 个值存储在分区表或未分区表的偏斜信息中。这适用于新创建的表和现有表。
计算 top K 的算法基于本文:数据流中频繁和 Top-k 元素的高效计算

Implementation

前 K 个统计信息与分区级别统计信息一起收集。 IStatsAggregator 接口需要添加一个方法 aggregateStatsTopK(),该方法从临时存储中读取多个条目:

...

public interface IStatsAggregator {

...

  /**
 * This method aggregates top K statistics.
   *
 * */
  public List<String> aggregateStatsTopK(String keyPrefix, String statType);

...

}

Usage

默认情况下,前 K 个统计信息处于禁用状态。用户可以将布尔变量 hive.stats.topk.collect 设置为 true 以启用计算前 K 并将前 K 放入倾斜的信息中。

set hive.stats.topk.collect=true;

用户还可以通过设置整数变量 hive.stats.topk.num 来指定 K 的数量,并可以通过设置 float 变量来指定值必须保持在前 K 个结果中的最小行百分比。 hive.stats.topk.minpercent

set hive.stats.topk.num=8;
set hive.stats.topk.minpercent=5.0;

另一个整数变量 hive.stats.topk.poolsize ,指定了计算前 K 个值时要监视的值的数量。前 K 个估计值的准确性随着此数字的增大而增加。

set hive.stats.topk.poolsize=200;

同时为大量分区计算 top K 可能会给内存带来压力。用户可以指定整数变量 hive.stats.topk.maxpartnum 作为要收集 Top K 的最大分区数。超过此数目时,将为所有其余分区禁用 topK。

set hive.stats.topk.maxpartnum=10;

如果使用 JDBC 实现临时存储的统计信息(例如 Derby 或 MySQL),则用户还应通过设置变量 hive.stats.topk.column.type 为 top K 指定列类型。默认情况下, TEXT 用于 MySQL, LONG VARCHAR 用于 Derby。

set hive.stats.topk.column.type='LONG VARCHAR';

Example

用户可以在开始时设置与前 K 个相关的变量:

set hive.stats.topk.collect=true;
set hive.stats.topk.num=4;
set hive.stats.topk.minpercent=0;
set hive.stats.topk.poolsize=100;

新创建的表

假设创建一个没有歪斜的分区表,并且将数据插入到其分区中:

CREATE TABLE table1 (key STRING, value STRING) PARTITIONED BY (ds STRING);
INSERT OVERWRITE TABLE table1 PARTITION (ds='2012-09-07') SELECT * FROM table_src;

插入数据时计算分区的前 K 个。如果用户发出命令:

DESCRIBE FORMATTED table1 partition (ds='2012-09-07');

然后在输出中,将显示以下内容:

...
Skewed Columns:         [value]                  
Skewed Values:          [[val_348], [val_230], [val_401], [val_70]]      
...

如果用户发出命令:

DESCRIBE FORMATTED table1;

那么在输出中,就不会有偏斜的信息,因为表级别的前 K 不适用于分区表。

对于非分区表:

CREATE TABLE table1 (key STRING, value STRING);
INSERT OVERWRITE TABLE table1 SELECT * FROM table_src;

如果用户发出命令:

DESCRIBE FORMATTED table1;

然后在输出中,将显示以下内容:

...
Skewed Columns:         [value]                  
Skewed Values:          [[val_348], [val_230], [val_401], [val_70]]      
...

使用倾斜创建表时:

set hive.internal.ddl.list.bucketing.enable=true;
CREATE TABLE table1 (key STRING, value STRING) PARTITIONED BY (ds STRING) SKEWED BY (key) on ('38', '49');
INSERT OVERWRITE TABLE table1 PARTITION (ds='2012-09-07') SELECT * FROM table_src;

将不收集前 K 个,并且保留用户指定的偏斜信息。如果用户发出命令:

DESCRIBE FORMATTED table1 partition (ds='2012-09-07');

然后在输出中,将显示以下内容:

...
Skewed Columns:         [key]                    
Skewed Values:          [[38], [49]]   
...

Existing Tables

Top K 对 ANALYZE 命令和 INSERT 命令的工作方式相同。

当前状态(JIRA)

See HIVE-3421.