Goal

顶级问题如下:

有许多以下格式的表:

并且以下查询需要有效地执行:

“ x”的基数在 T 的每个分区中为 1000.此外,“ x”的值存在偏差。通常,大约 x 的'x'值具有很大的偏斜,而剩余的'x'值具有小的基数。另外,请注意,此 Map(具有高基数的“ x”值)可以每天更改。

上述要求可以通过以下方式解决:

Basic Partitioning

为值“ x”创建一个分区。

List Bucketing

这里的基本思想如下:识别倾斜度高的键。每个偏斜的密钥都有一个目录,其余的密钥进入一个单独的目录。此 Map 在表或分区级别的元存储中维护,并且由 Hive 编译器用来进行 Importing 修剪。倾斜键的列表存储在表级别。 (请注意,此列表最初可以由 Client 端定期提供,最终可以在加载新分区时进行更新.)

例如,该表维护着'x'的倾斜键的列表:6、20、30、40.加载新分区时,它将创建 5 个目录(倾斜键的 4 个目录,其余所有默认目录 1 个)键)。已加载的表/分区将具有以下 Map:6,20,30,40,others。这类似于当前的哈希存储桶,其中存储桶号确定文件号。由于倾斜键不需要连续,因此倾斜键的整个列表需要存储在每个表/分区中。

当查询表格

发出后,Hive 编译器仅将与 x = 30 对应的目录用于 map-reduce 作业。

查询表格

Hive 编译器仅将与 x = others 对应的文件用于 map-reduce 作业。

在以下假设下,此方法是好的:

当有多个集群密钥时,可以将此方法扩展到方案。假设我们要优化表单查询

可以轻松优化所有指定了聚类键的查询。但是,使用某些指定的群集键的查询:

只能用于修剪很少的目录。是否指定聚类键的前缀并不重要。例如对于 x = 10,Hive 编译器可以修剪对应于(20,'c')的文件。对于 y ='b',可以删除与(10,'a')和(20,'c')相对应的文件。如果未指定完整密钥,则对其他人的哈希处理并没有 true 的帮助。

在以下情况下,此方法无法扩展:

歪斜表与列表存储区表

可以将普通的倾斜表用于倾斜联接等。(请参见偏斜连接优化设计文档。)如果不使用列表存储功能,则无需将其定义为列表存储表。

清单桶验证

主要由于其子目录的性质,列表存储不能与某些功能共存。

DDL

如果列表存储表与以下文件共存,则将引发编译错误

DML

如果列表存储表与以下文件共存,则将引发编译错误

分区值不应与默认列表存储目录名称相同。

Alter Table 串联

如果列表存储表与以下文件共存,则将引发编译错误

Hive Enhancements

Hive 需要扩展以支持以下内容:

Create Table

CREATE TABLE <T> (SCHEMA) SKEWED BY (keys) ON ('c1', 'c2') [STORED AS DIRECTORIES];

该表将是一个倾斜的表。将为所有分区创建倾斜的信息。

For example:

“按目录存储”是一个可选参数。它告诉 Hive,它不仅是歪斜的表,而且列表存储功能也应适用:为歪斜的值创建子目录。

Alter Table

倾斜的修改表

ALTER TABLE <T> (SCHEMA) SKEWED BY  (keys) ON ('c1', 'c2') [STORED AS DIRECTORIES];

仅在表级别而非分区级别支持以上功能。

It will

会影响

Alter Table 不倾斜

ALTER TABLE <T> (SCHEMA) NOT SKEWED;

以上将

会影响

更改表未存储为目录

ALTER TABLE <T> (SCHEMA) NOT STORED AS DIRECTORIES;

以上将

更改表设置的偏斜位置

ALTER TABLE <T> (SCHEMA) SET SKEWED LOCATION (key1="loc1", key2="loc2");

上面将更改列表存储区位置图。

Design

加载此类表时,最好为每个倾斜的键创建一个子目录。可以使用类似于动态分区的基础结构。

Alter table <T> partition <P> concatenate;需要更改以合并每个目录中的文件。

Implementation

Version information

列表存储区已在 Hive 0.10.0 和 0.11.0 中添加。

HIVE-3026是列表存储功能的 JIRA 根票证。它具有指向其他 JIRA 票证的链接,这些票证在 Hive 中实现列表存储,包括:

有关更多信息,请参见DDL 文档中的歪斜表

首页