为Delta表使用液态聚类
Liquid clustering通过简化数据布局决策来优化查询性能,改进了现有的分区和ZORDER技术。它提供了在不重写现有数据的情况下重新定义聚类列的灵活性,使数据布局能够随着分析需求的变化而逐步演进。
注意
此功能在Delta Lake 3.1.0及以上版本中可用。请参阅限制。
什么是液态集群(Liquid Clustering)的用途?
以下是受益于集群化的示例场景:
表经常通过高基数列进行过滤。
数据分布存在显著倾斜的表。
快速增长且需要维护和调优的表。
访问模式随时间变化的表。
表中典型的分区列可能导致分区数量过多或过少的情况。
启用液态聚类
您可以在现有表上或创建表时启用液态聚类。聚类与分区或ZORDER不兼容。启用后,照常运行OPTIMIZE作业以增量式聚类数据。详见How to trigger clustering。
要启用液态聚类功能,请在创建表语句中添加CLUSTER BY短语,如下例所示:
注意
在 Delta Lake 3.2 及以上版本中,您可以使用 Python 或 Scala 中的 DeltaTable API 来启用液态集群。
-- 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;
# Create an empty table
DeltaTable.create()
.tableName("table1")
.addColumn("col0", dataType = "INT")
.addColumn("col1", dataType = "STRING")
.clusterBy("col0")
.execute()
// Create an empty table
DeltaTable.create()
.tableName("table1")
.addColumn("col0", dataType = "INT")
.addColumn("col1", dataType = "STRING")
.clusterBy("col0")
.execute()
警告
使用液态聚类创建的表启用了Clustering和DomainMetadata表特性(均为写入特性),并使用Delta写入版本7和读取版本1。表协议版本无法降级。参见How does Delta Lake manage feature compatibility?。
在 Delta Lake 3.3 及以上版本中,您可以使用以下语法在现有的未分区 Delta 表上启用液态聚类:
ALTER TABLE <table_name>
CLUSTER BY (<clustering_columns>)
重要
默认行为不会对先前写入的数据应用聚类。要强制对所有记录重新聚类,必须使用OPTIMIZE FULL。参见Recluster entire table。
选择聚类列
聚类列可以按任意顺序定义。如果两列存在相关性,只需将其中一列添加为聚类列即可。
如果您正在转换现有表,请考虑以下建议:
当前数据优化技术 |
聚类列建议 |
|---|---|
Hive风格分区 |
将分区列用作聚类列。 |
Z-order索引 |
使用 |
Hive风格的分区和Z排序 |
同时使用分区列和 |
生成列以降低基数(例如,时间戳对应的日期) |
使用原始列作为聚类列,不要创建生成列。 |
如何触发聚类
在您的表上使用OPTIMIZE命令,如下例所示:
OPTIMIZE table_name;
Liquid聚类是增量式的,意味着仅在必要时重写数据以容纳需要聚类的数据。已经聚类且具有不同聚类列的数据文件不会被重写。
从集群表中读取数据
您可以使用任何Delta Lake客户端读取集群表中的数据。为了获得最佳查询结果,请在查询过滤器中包含聚类列,如下例所示:
SELECT * FROM table_name WHERE clustering_column_name = "some_value";