查询 Iceberg 表数据并执行时间旅行 - Amazon Athena
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

查询 Iceberg 表数据并执行时间旅行

若要查询 Iceberg 数据集,请使用标准 SELECT 语句,如下所示。查询遵循 Apache Iceberg 格式 v2 规范,并对位置和平等删除执行读取时合并。

SELECT * FROM [db_name.]table_name [WHERE predicate]

为了优化查询时间,所有谓词都会向下推送到数据所在的位置。

时间旅行和版本旅行查询

每个 Apache Iceberg 表都维护所包含 Amazon S3 对象的版本控制清单。清单的早期版本可用于时间旅行和版本旅行查询。

Athena 中的时间旅行查询在 Amazon S3 中查询一致快照中截至指定日期和时间的历史数据。Athena 中的版本旅行查询在 Amazon S3 中查询指定快照 ID 以前的历史数据。

时间旅行查询

要运行时间旅行查询,请在 SELECT 语句中的表名称之后使用 FOR SYSTEM_TIME AS OF timestamp,如下例所示。

SELECT * FROM iceberg_table FOR SYSTEM_TIME AS OF timestamp

为旅行指定的系统时间可以是时间戳,也可以是带时区的时间戳。如果未指定,Athena 将该值视为以 UTC 时间表示的时间戳。

以下示例时间旅行查询选择指定日期和时间的 CloudTrail 数据。

SELECT * FROM iceberg_table FOR SYSTEM_TIME AS OF TIMESTAMP '2020-01-01 10:00:00'
SELECT * FROM iceberg_table FOR SYSTEM_TIME AS OF (current_timestamp – interval '1' day)

版本旅行查询

要执行版本旅行查询(即,查看指定版本以前的一致快照),请在 SELECT 语句中的表名称之后使用 FOR SYSTEM_VERSION AS OF version,如下例所示。

SELECT * FROM [db_name.]table_name FOR SYSTEM_VERSION AS OF version

version 参数是与 Iceberg 表版本关联的 bigint 快照 ID。

以下示例版本旅行查询选择指定版本的数据。

SELECT * FROM iceberg_table FOR SYSTEM_VERSION AS OF 949530903748831860

检索快照 ID

您可以在 JavaPython 中使用 Iceberg 提供的 SDK 以检索 Iceberg 快照 ID。以下是 Java 中的示例。

import org.apache.iceberg.Table; import org.apache.iceberg.aws.glue.GlueCatalog; import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.util.SnapshotUtil; import java.text.SimpleDateFormat; import java.util.Date; Catalog catalog = new GlueCatalog(); Map<String, String> properties = new HashMap<String, String>(); properties.put("warehouse", "s3://my-bucket/my-folder"); catalog.initialize("my_catalog", properties); Date date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2022/01/01 00:00:00"); long millis = date.getTime(); TableIdentifier name = TableIdentifier.of("db", "table"); Table table = catalog.loadTable(name); long oldestSnapshotIdAfter2022 = SnapshotUtil.oldestAncestorAfter(table, millis);

结合使用时间旅行和版本旅行

您可以在同一查询中使用时间旅行和版本旅行语法来指定不同的时间和版本控制条件,如以下示例所示。

SELECT table1.*, table2.* FROM [db_name.]table_name FOR SYSTEM_TIME AS OF (current_timestamp - interval '1' day) AS table1 FULL JOIN [db_name.]table_name FOR SYSTEM_VERSION AS OF 5487432386996890161 AS table2 ON table1.ts = table2.ts WHERE (table1.id IS NULL OR table2.id IS NULL)