使用分区索引 - AWS Glue
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用分区索引

随着时间的推移,表中添加数十万个分区。API 用于提取表中的分区。GetPartitionsAPI 将返回与请求中提供的表达式匹配的分区。

我们将 sales_data 表作为示例,按键 CountryCategoryYearMonth 进行分区。如果要获取 2020图书类别中所有已售商品的销售数据,您必须使用表达式“类别 = 图书和年份 = 2020”向 GetPartitions 发出 Data Catalog 请求。

如果表上不存在分区索引,则 AWS Glue 加载表的所有分区,然后使用 GetPartitions 请求中用户提供的查询表达式筛选已加载的分区。由于分区数会增加,查询需要更长的时间运行在没有索引的表上。利用索引,GetPartitions 查询将尝试提取分区的子集,而不是加载表中的所有分区。

关于分区索引

创建分区索引时,您可以指定给定表上已存在的分区键列表。分区索引是在表中定义的分区键的子列表。可以在表上定义的任何分区键排列上创建分区索引。对于上述 sales_data 表,可能的索引包括 (国家/地区、类别、年份、月份)、(国家/地区、类别、年份、年份)、(国家/地区)、(国家/地区)、(国家/地区、国家/地区、年份、月份等)。

将按创建索引时提供的顺序连接分区值。Data Catalog由于分区添加到表中,因此索引是一致地构建的。可以为 String 和 Numberic(int、igint、long、minit 和 smallint)列类型创建索引。例如,对于分区键为 country(字符串)、item(字符串)、creationDate(日期)的表,不能在分区键 creationDate 上创建索引。

数字数据类型的索引支持 =、>、>=、<= 以及运算符之间。字符串数据类型仅支持等于 (=) 运算符。索引解目前仅支持 AND 逻辑运算符。在表达式中将忽略具有运算符“LIKE”、“IN”、“OR”和“NOT”的子表达式,以便使用索引进行筛选。在应用索引筛选后,将对提取的分区执行忽略的子表达式的筛选。

对于添加到表的每个分区,都会创建相应的索引项目。对于具有“n”分区的表,1 分区索引将生成“n”分区索引项目。同一表上的“m”分区索引将生成“m*n”分区索引项目。每个分区索引项将根据数据目录存储的当前 AWS Glue 定价策略收费。有关存储对象定价的详细信息,请参阅 AWS Glue 定价

创建具有分区索引的表

您可以在表创建期间创建分区索引。请求将 CreateTablePartitionIndex 对象列表作为输入。最多可在给定表上创建 3 个分区索引。每个分区索引都需要为表定义的一个名称和一个 partitionKeys 列表。在表上创建的索引可以使用 GetPartitionIndexes API 提取

向现有表添加分区索引

要将分区索引添加到现有表,请使用 CreatePartitionIndex 操作。您可以为每个 PartitionIndex 操作创建一个 CreatePartitionIndex。添加索引不会影响表的可用性,因为在创建索引时表继续可用。

添加的分区的索引状态设置为 CREATING 并开始创建索引数据。如果创建索引的过程成功,则 indexStatus 将更新为 ACTIVE,对于不成功的过程,索引状态将更新为 FAILED。索引创建可能会由于多种原因而失败,并且您可以使用 GetPartitionIndexes 操作来检索失败详细信息。可能的故障包括:

  • ENCRYPTED_PARTITION_ERROR – 不支持在具有加密分区的表上创建索引。

  • INVALID_PARTITION_TYPE_DATA_ERROR – 当 partitionKey 值不是相应 partitionKey 数据类型的有效值时观察。例如:具有“int”数据类型的 partitionKey 具有值“foo”。

  • MISSING_PARTITION_VALUE_ERROR – 在 partitionValueindexedKey 不存在时观察到。当表未得到一致分区时,可能会发生此情况。

  • UNSUPPORTED_PARTITION_CHARACTER_ERROR – 当索引分区键的值包含字符 \\u0000、\\u0001 或 \\u0002 时观察到

  • INTERNAL_ERROR – 创建索引时发生内部错误。

描述表的分区索引

要获取在表上创建的分区索引,请使用 GetPartitionIndexes 操作。响应将返回表上的所有索引以及每个索引的当前状态 (IndexStatus)。

分区索引的 IndexStatus 为下列项之一:

  • CREATING – 索引当前正在创建,尚不可用。

  • ACTIVE – 索引已准备就绪,可供使用。请求可以使用索引执行优化的查询。

  • DELETING – 当前正在删除索引,并且不再可用。可以使用 DeletePartitionIndex 请求删除处于活动状态的索引,这会将状态从 ACTIVE 移动到 DELETING。

  • FAILED – 现有表上的索引创建失败。每个表存储最后 10 个失败的索引。

在现有表上创建的索引的可能状态转换包括:

  • CREATING → ACTIVE → DELETING

  • CREATING → FAILED (正在创建 → 失败)

使用分区索引的限制

创建分区索引后,请注意对表和分区功能的以下更改:

新分区创建(在添加索引后)

在表上创建分区索引后,将验证添加到表的所有新分区以检查索引键的数据类型。将验证索引键的分区值是否有数据类型格式。如果数据类型检查失败,则创建分区操作将失败。对于 sales_data 表,如果为类别的类型为 string、年份类型为 int 的键(类别、年份)创建索引,则创建新分区的值将为“foo”的新分区将失败。

启用索引后,添加其索引键值为 U+0000、U+000001 和 U+0002 的分区将开始失败。

表更新

在表上创建分区索引后,您无法修改现有分区键的分区键名称,也无法更改在索引中注册的键的类型或顺序。

在 Athena 中创建表作为选择 (CTAS) 语句

具有分区索引的表不支持 INSERT INTO 选项。具有分区索引的表不能在 Athena 上使用 INSERT INTO 命令。如果在表上创建索引,INSERT INTO 查询将失败并显示消息“HIVE_METASTORE_ERROR:分区创建无法完成,因为在表上启用了分区索引”。

有限支持

来自 Athena、Redshift Spectrum 和 AWS Glue ETL 的调用当前不使用索引来提取分区。目前,来自 EMR 的目录请求可以使用索引来提取分区。

对优化的 GetPartitions 调用使用索引

当您对带索引的表调用 GetPartitions 时,您可以包含表达式,如果适用,数据目录将尽可能使用索引。索引的第一个键应传入表达式,以便让索引用于筛选。尽可能应用筛选中的索引优化。尝试尽可能多地使用索引优化,但如果缺少索引或运算符不受支持,则会回退到加载所有分区的现有实施。Data Catalog

对于上面的 sales_data 表,我们添加索引 [Country, Category, Year]。如果未在表达式中传递“Country”,则注册的索引将无法使用索引筛选分区。您最多可以添加 3 个索引以支持各种查询模式。

我们来看一些示例表达式,并了解索引在它们的工作原理:

表达式 如何使用索引

国家/地区 = '美国'

索引将用于筛选分区。

国家/地区 = '美国',类别 = '鞋子'

索引将用于筛选分区。

类别 = 'Shoes'

不会使用索引,因为表达式中未提供“country”。将加载所有分区以返回响应。

国家/地区 = '美国'和类别 = '鞋子'和年份 > '2018'

索引将用于筛选分区。

国家/地区 = '美国'和类别 = '简单'和年份 > '2018',月份 = 2

索引将用于提取国家/地区 = "US" 且类别 = "shoes" 和年份 > 2018 的所有分区。然后,将对月份表达式执行筛选。

国家/地区 = '美国' AND 类别 = '鞋子'或年份 > '2018'

不会将索引用作表达式中存在的 OR 运算符。

国家/地区 = '美国' AND 类别 = '简单' AND (年份 = 2017 或年份 = '2018')

索引将用于提取国家/地区 =“US”且类别 =“shoes”的所有分区,然后对年份表达式执行筛选。

('US'、'UK') AND 类别 = 'Shoes'

索引将不会用于筛选,因为当前不支持 IN 运算符。