本文介绍如何通过Optimize和Vacuum命令优化表。
Optimize
- Scala
import io.delta.tables._ val deltaTable = DeltaTable.forPath(spark, "/tmp/delta_table") deltaTable.optimizeExpr("date < '2019-11-11'", Seq("date", "id")) // 使用SQL字符串。 import org.apache.spark.sql.functions._ import spark.implicits._ deltaTable.optimize(col("date < '2019-11-11'"), Seq(col("date"), col("id"))) // 使用SQL函数和隐式转换。
- SQL
OPTIMIZE delta_table [WHERE t.date < '2019-11-11'] [ZORDER BY t.date,t.id];
当
deltaTable.optimize()
不指定参数时,表示对全表进行优化。说明 从EMR-3.27.0版本开始支持ZOrder功能。
Vacuum
通过Optimize后,小文件会被合并为大文件,并且小文件被标记为墓碑文件。因为Delta有访问历史的功能,所以原有小文件不会被删除,当访问历史版本时,仍然需要读取小文件,影响优化表的执行效率。
Vacuum用于清理历史文件。如果墓碑文件涉及的数据过时很久,可以用Vacuum命令将其物理删除。默认情况下,墓碑文件只有经过一个安全期才能被删除,如果删除一个尚在安全期内的文件,将会抛出异常。
如果您要删除近期的墓碑文件,例如1天前的墓碑文件,可通过以下两种方式:
- 设置合理的安全期参数(推荐):
spark.databricks.delta.properties.defaults.deletedFileRetentionDuration
、interval 1 day
、2 weeks
、365 days
等。不支持设置Month
和Year
。这些参数为表的静态属性,无法通过命令行或者设置--conf
来实现。其设置方法为:- 在spark-default.conf中配置全局属性。
- 通过
ALTER TABLE <tbl> SET PROPERTIES (key=value)
更改此表属性。
- 通过关闭安全期检查(不推荐):设置
set spark.databricks.delta.retentionDurationCheck.enabled = flase
关闭后,即可删除近期合并过的小文件。
注意
- 不建议关闭安全期检查。
- 不建议安全期设置过小。
过小的安全期可能导致正在读取某一历史版本的作业失败。甚至导致当前执行作业产生的临时文件被清理掉,从而导致作业失败。
- Scala
import io.delta.tables._ val deltaTable = DeltaTable.forPath(spark, pathToTable) deltaTable.vacuum() // 物理删除超出安全期的墓碑文件。 deltaTable.vacuum(100) // 物理删除100小时前的墓碑文件。
- SQL
VACUUM table_name [RETAIN num HOURS] [DRY RUN]
相关介绍如下:- 通过
RETAIN
子句指定删除超出设置时间间隔的墓碑文件。RETAIN num HOURS
的默认值为spark.databricks.delta.properties.defaults.deletedFileRetentionDuration
指定的值。 - 如果指定了DRY RUN,被删除文件不会被实际删除。
- 通过
在文档使用中是否遇到以下问题
更多建议
匿名提交