了解不可变性约束

不可变性约束允许您将动态表的某些部分标记为静态。定义不可变性约束时,Snowflake 会在刷新期间跳过这些行,从而提高性能,特别适用于包含大量历史数据的表。

在创建或更改动态表时,您可以使用 IMMUTABLE WHERE 子句定义不可变性约束。该子句会指定一个条件或谓词,用于标识哪些行不可变。

关键行为:

  • 初始刷新:在初始刷新期间,Snowflake 会忽略 IMMUTABLE WHERE 谓词,但在后续所有刷新中生效。

  • 完全刷新模式下:谓词仅对不符合条件的行重新计算。

  • 增量刷新:流和增量刷新动态表可以从具有不可变性约束的全量刷新动态表中读取。

  • 克隆和复制:Snowflake 会复制 IMMUTABLEWHERE 约束,没有任何限制。

有关计算成本的信息,请参阅 计算不变性约束的成本

何时使用不可变性约束

不可变性约束在以下场景中很有用:

避免重新处理历史数据

当动态表包含您不想重新处理的历史数据时,请将较旧的行标记为不可变。

优化全量刷新模式

采用全量 刷新模式 的动态表通常在每次刷新期间重新计算所有行。不可变性约束仅限重新计算可变行,从而显著减少了大多数数据为历史数据时的工作量。

促进增量下游刷新

某些查询结构,例如 Python 用户定义的表函数,需要动态表采用全量刷新模式。通常,这会阻止下游表从增量刷新中受益。当上游表具有不可变性约束时,下游表仍然可以从增量处理中受益。

使用具有不可变性的回填

回填扩展了不可变性约束。回填是一种零复制操作,让您可以立即将现有数据复制到动态表,而无需重新计算。借此可以迁移现有管道、更改动态表定义,或在创建包含多年历史数据的表时避免昂贵的初始化。

回填的数据在未来刷新期间无法更改。

在创建同时包含 IMMUTABLE WHEREBACKFILL FROM 的动态表时:

  • 回填从源表中复制 不可变区域。不可变区域包含与 IMMUTABLE WHERE 条件匹配的行。

  • 查询定义会计算 可变区域。可变区域包含与条件不匹配的行。

与主键和唯一约束条件的交互 (RELY)

动态表可以使用 RELY 属性 设置 主键和唯一约束条件。当动态表满足以下两个条件时:

  • 设置了 IMMUTABLE WHERE 谓词,并且

  • 至少一个主键或唯一约束条件有 RELY 属性集,

IMMUTABLE WHERE 谓词中引用的列必须是该表中所有 RELY 主键和 RELY 唯一约束条件所引用列的子集。仅带有 RELY 属性的约束条件包含在允许的列集中(如果存在)。请参考以下示例:

  • 如果表在列 A 有一个 RELY 主键,而在列 B 有一个 NORELY 唯一约束条件,则 IMMUTABLE WHERE 谓词只能引用列 ``A``(或 RELY 约束条件列的子集)。

  • 如果表在列 A 有一个 RELY 主键,在列 B 有一个 RELY 唯一约束条件,并在列 C 有一个 NORELY 唯一约束条件,则 IMMUTABLE WHERE 谓词只能引用列 AB,或它们的任意子集。

在添加或修改 RELY 约束条件或 IMMUTABLE WHERE 谓词时,会进行有效性检查。如果生成的状态违反规则(例如,谓词引用了不在任何 RELY 约束条件中的列),则语句失败并显示错误。

后续步骤

有关实施指南和示例,请参阅 回填示例Immutability constraints