跳到内容

为 Delta 表使用液态集群

Liquid Clustering 通过简化数据布局决策来优化查询性能,从而改进了现有的分区和 ZORDER 技术。Liquid Clustering 提供了重新定义集群列的灵活性,而无需重写现有数据,允许数据布局随时间推移与分析需求一同演进。

以下是受益于集群的场景示例

  • 经常通过高基数列进行过滤的表。
  • 数据分布存在显著倾斜的表。
  • 增长迅速且需要维护和调优工作的表。
  • 访问模式随时间变化的表。
  • 典型分区列可能导致表分区过多或过少的表。

您可以在现有表上启用 Liquid Clustering,也可以在创建表时启用。集群与分区或 ZORDER 不兼容。启用后,照常运行 OPTIMIZE 作业以增量集群数据。请参阅如何触发集群

要启用 Liquid Clustering,请在表创建语句中添加 CLUSTER BY 短语,如下面的示例所示

-- Create an empty table
CREATE TABLE table1(col0 int, col1 string) USING DELTA CLUSTER BY (col0);
-- Using a CTAS statement (Delta 3.3+)
CREATE EXTERNAL TABLE table2 CLUSTER BY (col0) -- specify clustering after table name, not in subquery
LOCATION 'table_location'
AS SELECT * FROM table1;

在 Delta Lake 3.3 及更高版本中,您可以使用以下语法在现有未分区的 Delta 表上启用 Liquid Clustering

ALTER TABLE <table_name>
CLUSTER BY (<clustering_columns>)

集群列可以按任何顺序定义。如果两个列相关,您只需将其中一个列添加为集群列。

如果您正在转换现有表,请考虑以下建议

当前数据优化技术集群列的建议
Hive 样式分区使用分区列作为集群列。
Z-order 索引使用 ZORDER BY 列作为集群列。
Hive 样式分区和 Z-order同时使用分区列和 ZORDER BY 列作为集群列。
用于减少基数(例如,时间戳的日期)的生成列使用原始列作为集群列,并且不创建生成列。

您必须使用支持 ClusteringDomainMetadata 表功能的 Delta 写入器客户端。

使用 OPTIMIZE 命令对您的表进行操作,如下面的示例所示

sql OPTIMIZE table_name;

Liquid Clustering 是增量的,这意味着数据仅在需要集群时才进行重写。已集群且具有不同集群列的数据文件不会被重写。

在 Delta Lake 3.3 及更高版本中,您可以使用以下语法强制重新集群表中的所有记录

sql OPTIMIZE table_name FULL;

更改集群列时运行 OPTIMIZE FULL。如果您以前运行过 OPTIMIZE FULL 并且集群列没有变化,OPTIMIZE FULL 的运行方式与 OPTIMIZE 相同。始终使用 OPTIMIZE FULL 来确保数据布局反映当前集群列。

您可以使用任何 Delta Lake 客户端读取集群表中的数据。为获得最佳查询结果,请在查询过滤器中包含集群列,如下面的示例所示

您可以随时通过运行 ALTER TABLE 命令更改表的集群列,如下面的示例所示

sql ALTER TABLE table_name CLUSTER BY (new_column1, new_column2);

当您更改集群列时,后续的 OPTIMIZE 和写入操作将使用新的集群方法,但现有数据不会被重写。

您还可以通过将列设置为 NONE 来关闭集群,如下面的示例所示

sql ALTER TABLE table_name CLUSTER BY NONE;

将集群列设置为 NONE 不会重写已集群的数据,但会阻止未来的 OPTIMIZE 操作使用集群列。

您可以使用 DESCRIBE DETAIL 命令查看表的集群列,如下面的示例所示

sql DESCRIBE DETAIL table_name;

存在以下限制

  • 您只能指定收集了统计信息的列作为集群列。默认情况下,Delta 表中的前 32 列会收集统计信息。
  • 您最多可以指定 4 个集群列。