优化数据文件布局

预测优化会在 Unity Catalog 托管表上自动运行 OPTIMIZE。 Databricks 建议为所有 Unity Catalog 托管表启用预测优化,以简化数据维护并降低存储成本。 请参阅 Unity Catalog 托管表的预测性优化

OPTIMIZE 命令重写数据文件以改善 Delta 表的数据布局。 对于启用了 liquid 聚类分析的表,OPTIMIZE 会重写数据文件以按 liquid 聚类分析键对数据进行分组。 对于定义了分区的表,文件压缩和数据布局在分区内执行。

未启用 liquid 聚类分析的表可以选择包含 ZORDER BY 子句,以改进重写时的数据聚类分析。 Databricks 建议使用 liquid 聚类分析,而不要使用分区、ZORDER 或其他数据布局方法。

请参阅 OPTIMIZE

语法示例

通过运行 OPTIMIZE 命令触发压缩:

SQL

OPTIMIZE table_name

Python

from delta.tables import *
deltaTable = DeltaTable.forName(spark, "table_name")
deltaTable.optimize().executeCompaction()

Scala

import io.delta.tables._
val deltaTable = DeltaTable.forName(spark, "table_name")
deltaTable.optimize().executeCompaction()

如果拥有大量数据,并且只想要优化其中的一个子集,则可以使用 WHERE 指定一个可选的分区谓词:

SQL

OPTIMIZE table_name WHERE date >= '2022-11-18'

Python

from delta.tables import *
deltaTable = DeltaTable.forName(spark, "table_name")
deltaTable.optimize().where("date='2021-11-18'").executeCompaction()

Scala

import io.delta.tables._
val deltaTable = DeltaTable.forName(spark, "table_name")
deltaTable.optimize().where("date='2021-11-18'").executeCompaction()

注意

  • 二进制打包优化幂等,这意味着如果在同一数据集上运行两次,则第二次运行不起作用。
  • 二进制打包旨在根据其在磁盘上的大小生成均匀平衡的数据文件,但不一定是每个文件的元组数。 但是,这两个度量值通常是相关的。
  • Databricks Runtime 11.3 LTS 及更高版本提供用于执行 OPTIMIZE 操作的 Python 和 Scala API。

Delta 表的读取器使用快照隔离,这意味着,当 OPTIMIZE 从事务日志中删除不必要的文件时,它们不会中断。 OPTIMIZE 不会对表进行任何数据相关更改,因此,在 OPTIMIZE 之前和之后读取都具有相同的结果。 对作为流式处理源的表执行 OPTIMIZE 不会影响将此表视为源的任何当前或未来的流。 OPTIMIZE 返回所删除文件的文件统计信息(最小值、最大值、总计等)和操作添加的文件。 优化统计信息还包含 Z 排序统计信息、批处理数和已优化分区数。

你还可以使用自动压缩来自动压缩小文件。 请参阅 Azure Databricks 上的 Delta Lake 的自动压缩

我应该多久运行一次 OPTIMIZE

对 Unity Catalog 托管表启用预测优化,以确保 OPTIMIZE 在经济高效时自动运行。

如果选择运行 OPTIMIZE 的频率,则会在性能和成本之间进行权衡。 为了提高最终用户查询性能,请更频繁地运行 OPTIMIZE。 由于资源使用量增加,这将产生更高的成本。 若要优化成本,请减少运行频率。

Databricks 建议从每天运行一次 OPTIMIZE 开始,然后调整频率以平衡成本和性能权衡。

运行 OPTIMIZE(二进制打包和 Z 排序)的最佳实例类型是什么?

这两个操作都是执行大量 Parquet 解码和编码的 CPU 密集型操作。

Databricks 建议使用计算优化实例类型。 此外,OPTIMIZE 也受益于附加的 SSD。