优化数据文件布局
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。