什么是分桶?
分桶是一种将数据集记录分为称为存储桶的类别的方法。
这里的存储桶和分桶的含义与 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 SELECT
(CTAS)查询中,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
BUCKETSINTO
子句指定用于对数据进行分桶的存储桶数。N
BUCKETS
在以下 CREATE TABLE
示例中,使用 Spark 算法按 customer_id
将 sales
数据集分为 8 个存储桶。CREATE TABLE
语句使用 CLUSTERED
BY
和 TBLPROPERTIES
子句相应地设置属性。
CREATE EXTERNAL TABLE sales (...) ... CLUSTERED BY (`customer_id`) INTO 8 BUCKETS ... TBLPROPERTIES ( 'bucketing_format' = 'spark' )
要使用 CREATE TABLE AS
指定分桶,使用 bucketed_by
和 bucket_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 最多读取每个分区中的一个文件。