外部表的分区发现

本文介绍 Unity Catalog 外部表的默认分区发现策略和一个可选设置,用于启用分区元数据日志,以使分区发现与 Hive 元存储保持一致。

Databricks 建议启用分区元数据日志记录,以提高具有分区的 Unity Catalog 外部表的读取速度和查询性能。

Unity Catalog 的默认分区发现策略是什么?

默认情况下,Unity Catalog 以递归方式列出表位置中的所有目录,以自动发现分区。 对于具有多个分区目录的大型表,这会增加许多表操作的延迟。

使用分区元数据日志记录

重要

此功能目前以公共预览版提供。

在 Databricks Runtime 13.3 LTS 及更高版本中,可以选择启用分区元数据日志记录,这是注册到 Unity Catalog 的外部表的分区发现策略。 此行为与 Hive 元存储中使用的分区发现策略一致。 此行为仅影响具有分区并使用 Parquet、ORC、CSV 或 JSON 的 Unity Catalog 外部表。 Databricks 建议启用新行为,以提高这些表的读取速度和查询性能。

重要

启用了分区元数据日志记录的表演示了分区发现的行为更改。 Unity Catalog 不会自动扫描表位置以查找分区,而是严格遵守在分区元数据中注册的分区。 请参阅手动添加、删除或修复分区元数据

此行为将成为未来 Databricks Runtime 版本中的默认值。 启用此功能的表只能使用 Databricks Runtime 13.3 LTS 及更高版本读取或写入。

注意

必须尝试使用 Databricks Runtime 12.2 LTS 或更低版本查询表,以确认它不使用新的分区日志行为。

启用分区元数据日志记录

若要对表启用分区元数据日志记录,必须为当前 SparkSession 启用 Spark conf,然后创建外部表。 只有在创建表的 SparkSession 中才需要此设置。 创建启用了分区元数据日志记录的表后,它将此设置保留为表元数据的一部分,并在所有后续工作负载中使用该功能。

以下语法演示如何使用 SQL 在笔记本中设置 Spark conf。 还可以在配置计算时设置 Spark 配置。

SET spark.databricks.nonDelta.partitionLog.enabled = true;

重要

只能在 Databricks Runtime 13.3 LTS 及更高版本中启用分区元数据日志记录的读取和写入表。 如果工作负载在 Databricks Runtime 12.2 LTS 或更低版本上运行,但必须与表交互,请不要使用此设置。

删除外部表时不会删除基础数据文件。 Databricks 建议使用 CREATE OR REPLACE 语法来升级表以使用分区元数据日志记录,如以下示例所示:

CREATE OR REPLACE TABLE <catalog>.<schema>.<table-name>
USING <format>
PARTITIONED BY (<partition-column-list>)
LOCATION 'abfss://<bucket-path>/<table-directory>';

Unity Catalog 对表和卷的路径重叠强制执行规则。 如果某个表已存在于该位置,则无法在数据文件集合中注册新的 Unity Catalog 表。

使用具有分区元数据的表

Databricks 建议对所有已注册到 Unity Catalog 的表使用表名进行所有读取和写入。 对于具有分区元数据的表,这可以保证添加到 Unity Catalog 的表注册的新分区,以及针对表的查询读取所有已注册分区。

对读取或写入使用基于路径的模式可能会导致分区被忽略或未注册到 Unity Catalog 元存储。 请参阅限制

列出分区

使用以下命令将注册到 Unity Catalog 的所有分区显示为分区元数据:

SHOW PARTITIONS <table-name>

若要检查是否已将单个分区注册到 Unity Catalog,请使用以下命令:

SHOW PARTITIONS <table-name>
PARTITION (<partition-column-name> = <partition-column-value>)

手动添加、删除或修复分区元数据

Unity Catalog 要求外部表的所有分区都包含在表注册期间使用 LOCATION 子句注册的目录中。

启用分区元数据后,将禁用表位置中分区的自动发现。 如果外部系统将数据写入表位置或使用基于路径的写入来添加或覆盖表中的记录,则必须手动修复分区元数据。

Azure Databricks 使用 Hive 样式的分区来存储 Parquet、ORC、CSV 和 JSON 支持的表。 Hive 样式的分区包含通过分区目录中的等号连接的键值对,例如 year=2021/month=01/

如果表使用 Hive 样式分区,则可以使用 MSCK REPAIR 将 Unity Catalog 中的分区元数据与表位置中存在的分区同步。 以下语法示例演示了常见操作:

-- Add and remove parition metadata to match directories in table location
MSCK REPAIR TABLE <table_name>  SYNC PARTITIONS;

-- Add partitions in the table location that are not registered as partition metadata
MSCK REPAIR TABLE <table_name> ADD PARTITIONS;

-- Drop partitions registered as partition metadata that are not in the table location
MSCK REPAIR TABLE <table_name> DROP PARTITIONS;

请参阅 REPAIR TABLE

手动指定其他分区类型的路径

如果表不使用 Hive 样式分区,则必须在添加分区时手动指定分区位置。 与 MSCK REPAIR 语法相比,手动指定分区还可以降低延迟,尤其是对于具有大量分区的表。 以下语法示例演示如何添加分区:

ALTER TABLE <table-name>
ADD PARTITION (<partition-column-name> = <partition-column-value>)
LOCATION 'abfss://<bucket-path>/<table-directory>/<partition-directory>';

还可以使用 ALTER TABLE 语法删除、重命名、恢复和设置分区的位置。 请参阅更改表分区

禁用新的分区元数据

Spark 将授予该控件,用于控制新表是否默认禁用分区元数据。 也可以显式禁用此行为。 以下语法使用 SQL 禁用 Spark conf:

SET spark.databricks.nonDelta.partitionLog.enabled = false;

这仅控制 SparkSession 中创建的表是否使用分区元数据。 若要禁用使用该行为的表上的分区元数据,必须在未启用 Spark conf 的 SparkSession 中删除并重新创建该表。

注意

虽然无法在 Databricks Runtime 12.2 LTS 或更低版本中读取或写入启用了分区元数据的表,但如果在 Unity Catalog 中有足够的权限,则可以针对这些表运行 DROPCREATE OR REPLACE TABLE 语句。

限制

存在以下限制:

  • 无法使用 Databricks Runtime 12.2 LTS 或更低版本读取或写入启用了分区元数据的表。
  • 使用目录路径读取表将返回所有分区,包括已手动添加或删除的任何分区。
  • 如果使用路径而不是表名称在表中插入或覆盖记录,则不会记录分区元数据。
  • 不支持 Avro 文件格式。