什么是分桶? - Amazon Athena

什么是分桶?

分桶是一种将数据集记录分为称为存储桶的类别的方法。

这里的存储桶分桶的含义与 Amazon S3 存储桶不同,不应与之混淆。在数据分桶中,具有相同属性值的记录会进入同一存储桶中。记录在存储桶之间尽可能均匀地分布,因此每个存储桶的数据量大致相同。

实际上,存储桶就是文件,哈希函数决定了记录进入哪个存储桶。分桶数据集的每个分区的每个存储桶将包含一个或多个文件。文件所属的存储桶以文件名编码。

分桶优势

如果数据集按特定属性进行分桶,并且您想要检索该属性具有特定值的记录,建议使用分桶。由于数据已分桶,Athena 可以使用该值来确定要查看的文件。例如,假设一个数据集按 customer_id 进行分桶,并且您想要查找特定客户的所有记录。Athena 确定包含这些记录的存储桶,并且仅读取该存储桶中的文件。

如果您的列具有高基数(即具有许多不同值)、分布均匀且您经常查询特定值,这些都适合作为分桶的依据。

注意

Athena 不支持使用 INSERT INTO 向分桶表添加新记录。

对分桶列进行筛选所支持的数据类型

您可以在具有特定数据类型的分桶列中添加筛选器。Athena 在具有以下数据类型的分桶列上支持筛选:

  • BOOLEAN

  • BYTE

  • DATE

  • DOUBLE

  • FLOAT

  • INT

  • LONG

  • SHORT

  • string

  • VARCHAR

Hive 和 Spark 支持

Athena 引擎版本 2 支持使用 Hive 存储桶算法对数据集进行分区,而 Athena 引擎版本 3 也支持 Apache Spark 分桶算法。Hive 分桶为默认设置。如果您的数据集使用 Spark 算法进行分桶,使用 TBLPROPERTIES 子句将 bucketing_format 属性值设置为 spark

注意

在一个 CREATE TABLE AS SELECTCTAS)查询中,Athena 的分区数量不能超过 100 个。同样,您可以使用 INSERT INTO 语句向目标表最多添加 100 个分区。

如果超过此限制,则可能会收到错误消息 HIVE_TOO_MANY_OPEN_PARTITIONS: Exceeded limit of 100 open writers for partitions/buckets(HIVE_TOO_MANY_OPEN_PARTITIONS:分区/存储桶超过 100 个打开的写入程序限制)。要绕过此限制,您可以使用一个 CTAS 语句和一系列 INSERT INTO 语句,每个后一种语句将创建或插入不超过 100 个分区。有关更多信息,请参阅 使用 CTAS 和 INSERT INTO 绕过 100 分区限制

要为现有分桶数据集创建表,使用 CLUSTERED BY (column) 子句后跟 INTO N BUCKETS 子句。INTO N BUCKETS 子句指定用于对数据进行分桶的存储桶数。

在以下 CREATE TABLE 示例中,使用 Spark 算法按 customer_idsales 数据集分为 8 个存储桶。CREATE TABLE 语句使用 CLUSTERED BYTBLPROPERTIES 子句相应地设置属性。

CREATE EXTERNAL TABLE sales (...) ... CLUSTERED BY (`customer_id`) INTO 8 BUCKETS ... TBLPROPERTIES ( 'bucketing_format' = 'spark' )

要使用 CREATE TABLE AS 指定分桶,使用 bucketed_bybucket_count 参数,如以下示例所示。

CREATE TABLE sales WITH ( ... bucketed_by = ARRAY['customer_id'], bucket_count = 8 ) AS SELECT ...

以下示例查询将查找特定客户在一周内购买的产品的名称。

SELECT DISTINCT product_name FROM sales WHERE sales_date BETWEEN '2023-02-27' AND '2023-03-05' AND customer_id = 'c123'

如果此表按 sales_date 进行分区并按 customer_id 进行分桶,则 Athena 可以计算出客户记录所在的存储桶。Athena 最多读取每个分区中的一个文件。