注意
Databricks 建议对所有托管表进行液体聚类分析。 对于使用 Apache Iceberg 的托管表,Unity Catalog 仅支持液态聚类,并将 PARTITION BY 列解释为聚类键。 请参阅 将分区表转换为液体聚类分析。
Azure Databricks上大多数小于 100 TB 的数据的表不需要分区。 Azure Databricks默认情况下对所有表使用 Delta Lake,并通过引入时间自动对未分区表中的数据进行群集化,因此无需手动优化即可获得类似分区的性能。 仅当自定义分区策略的效果优于这些默认方案时,才考虑采用它。 请参阅使用引入时间聚类。
自定义分区策略
Apache Spark 和 Delta Lake 的高级用户可能会识别优于默认 引入时间群集的分区策略。
警告
无效的分区策略可能会对查询性能产生负面影响,并且需要完全重写数据才能修复。 对于大型表,完全重写可能成本高昂且非常耗时。
若要将现有分区的 Delta Lake 表转换为液体聚类分析,请使用 ALTER TABLE ... REPLACE PARTITIONED BY WITH CLUSTER BY。 液体聚类分析适用于低基数列和高基数列,并避免静态分区常见的固定分区边界和小文件问题。 请参阅 将分区表转换为液体聚类分析。
分区列支持的数据类型
分区支持分区列的以下数据类型:
- Date
- 时间戳
- TimestampNTZ
- 时间间隔
- String
- Binary
- 布尔
- 整数、长、短、字节
- Float、Double、Decimal
分区列必须是顶层列。 不能按以下任一项进行分区:
- 复杂类型,例如
StructType、MapType、ArrayType或VariantType - 结构字段,如
struct_col.field。 Delta Lake 将结构字段PARTITIONED BY视为表达式而不是列引用。
若要按结构字段组织表,请改用液体聚类分析,它将结构字段识别为聚类分析键。 液体聚类分析是在结构字段上跳过数据的唯一方法,无需先将其提取到顶级列中。 请参阅对表使用 liquid 聚类分析。
最小尺寸建议
低于这些最小大小的分区可能会对查询性能产生负面影响,而不是改进查询性能。 在决定是否对表进行分区时,请考虑以下事项:
- 表格:
- 如果数据少于 1 TB,请不要进行分区。
- 如果数据超过 1 TB 到 100 TB,请使用液体聚类分析,而不是分区。 分区对性能产生负面影响的情况,很可能比带来性能提升的情况更常见。
- 使用 100 TB 或更多数据时,分区可能会提高性能,但 Databricks 建议先使用液体聚类分析并验证性能改进。
- 对于分区,请验证每个分区是否至少包含 1 GB 的数据。 包含少量较大分区的表的性能往往优于包含大量较小分区的表。
使用引入时间聚类
使用 Delta Lake 时,未分区的表会自动使用 摄取时间聚类。 引入时间可带来与基于日期时间字段的分区策略相当的查询性能提升,而无需手动优化或调整数据。
注意
为了在对表执行大量修改 UPDATE 或 MERGE 语句时保持引入时间聚类分析,Databricks 建议对与引入顺序匹配的列使用液体聚类分析,例如事件时间戳或创建日期。 请参阅对表使用 liquid 聚类分析。
Delta Lake 和 Parquet 的分区兼容性
Delta Lake 使用 Parquet 来存储数据,而一些分区的 Delta Lake 表的数据布局类似于使用 Apache Spark 存储的 Parquet 表。 Apache Spark 在以 Parquet 格式保存数据时使用 Hive 样式分区。 Hive 样式分区 不是 Delta Lake 协议的一部分,工作负荷不应依赖于此分区策略来与 Delta Lake 表交互。
Databricks 建议使用官方支持的客户端和 API 与 Delta Lake 中存储的数据进行交互。 许多 Delta Lake 功能打破了关于数据布局的某些假设,而这些假设可能曾适用于 Parquet、Hive,甚至更早版本的 Delta Lake 协议。
注意
为 Delta Lake 表启用列映射时,随机前缀会替换 Hive 样式分区的分区目录中的列名称。 请参阅 有关使用 Delta Lake 列映射重命名和删除列的说明。
Delta Lake 分区与其他数据湖的对比
在其他开放源代码技术(如 Apache Spark、Parquet、Hive 和 Hadoop)中有用的分区技术并不总是适用于Azure Databricks。 如果选择对表进行分区,请考虑以下事项:
- 事务不是按分区边界定义的。 由于 Delta Lake 通过事务日志确保 ACID ,因此不需要通过分区分隔一批数据,以确保原子性。
- Azure Databricks计算群集的数据区域与物理媒体无关。 引入湖仓的数据存储在云对象存储中。 在数据处理期间将数据缓存到本地磁盘存储时,Azure Databricks使用基于文件的统计信息来识别用于并行加载的最小数据量。
Z顺序和分区
注意
Databricks 建议对所有新表采用液体聚类而不是 Z 排序。 请参阅对表使用 liquid 聚类分析。
可以将 Z 顺序索引与分区一起使用,以加快大型数据集的查询速度。 大多数表使用 引入时间聚类分析 ,以避免需要优化 Z 顺序和分区。
根据分区边界和 Z 顺序规划查询优化策略时,请记住以下规则:
- Z 顺序需要
OPTIMIZE命令。 不能跨分区边界合并文件,因此 Z 顺序聚类只能在某个分区中发生。 对于未分区的表,可以在整个表中合并文件。 - 分区仅适用于低基数字段或已知基数字段(例如日期字段或物理位置),而不适用于高基数字段(例如时间戳)。 Z 顺序适用于所有字段,包括高基数字段和可能无限增大的字段(例如交易或订单表中的时间戳或客户 ID)。
- 不能对用于分区的字段进行 Z 排序。
Azure Databricks 如何围绕现有分区进行优化
许多客户从基于 Parquet 的数据湖迁移到 Delta Lake,例如,使用 CONVERT TO DELTA 语句将基于 Parquet 的现有表转换为 Delta Lake 表,而无需重写现有数据。 由于转换不会重写现有数据,因此大型表可能会继承以前的分区策略。
某些 Databricks 优化会在可能的情况下使用这些分区,从而缓解未针对 Delta Lake 优化的分区策略所带来的负面性能影响。
Delta Lake 和 Apache Spark 是开源技术。 虽然 Databricks 的功能减少了对分区的依赖,但开放源代码社区可能会生成可增加复杂性的新功能。