动态表的最佳实践

本主题提供了创建和管理动态表的最佳实践和重要注意事项。

一般最佳实践

使用 MONITOR 权限查看元数据

对于用户只需要查看动态表的元数据和 Information Schema 的情况(例如,数据科学家持有的角色),请使用对该动态表具有 MONITOR 权限的角色。虽然 OPERATE 权限授予了这一访问权限,但它也包括更改动态表的功能,因此 MONITOR 更适合用户不需要更改动态表的情况。

有关更多信息,请参阅 动态表访问控制

简化分组键中的复合表达式

如果分组键包含复合表达式而不是基础列,则在一个动态表中物化表达式,然后在另一个动态表中对物化列应用分组操作。有关更多信息,请参阅 运算符如何增量刷新

使用动态表实现缓慢变化维度

动态表可用于实现 1 类和 2 类缓慢变化维度 (SCDs)。从变更流中读取时,对按变更时间戳排序的每条记录键使用窗口函数。使用此方法后,动态表可以无缝处理无序发生的插入、删除和更新,以简化 SCD 的创建。有关详细信息,请参阅 使用动态表实现缓慢变化维度 (link removed)。

创建动态表的最佳实践

将动态表的管道链接在一起

定义新的动态表时,不要定义包含许多嵌套语句的大型动态表,而应使用小型动态表与管道组合的方式。

您可以设置动态表来查询其他动态表。例如,想象这样一个场景:您的数据管道从暂存表中提取数据以更新各种维度表(例如,客户、产品、日期和时间)。此外,管道还根据这些维度表中的信息更新汇总销售表。通过将维度表配置为查询暂存表,将聚合销售表配置为查询维度表,可以创建类似于任务图的级联效果。

在此设置中,仅在维度表刷新成功完成后才能执行汇总销售表的刷新。这样可以确保数据的一致性并达到滞后目标。通过自动刷新过程,源表中的任何更改都会在适当的时候触发对所有从属表的刷新。

任务图和动态表 DAGs 的比较

对复杂任务图使用“控制器”动态表

如果您有一个动态表的复杂图表,其中包含许多根节点和叶节点,并且您想使用单个命令对整个任务图执行操作(例如更改滞后、手动刷新、挂起),请执行以下步骤:

  1. 将所有动态表的 TARGET_LAG 值设置为 DOWNSTREAM

  2. 创建一个“控制器”动态表,从任务图中的所有叶中读取。要确保此控制器不消耗资源,请执行以下语句:

    CREATE DYNAMIC TABLE controller
      TARGET_LAG = <target_lag>
      WAREHOUSE = <warehouse>
      AS
        SELECT 1 A FROM <leaf1>, …, <leafN> LIMIT 0;
    
    Copy
  3. 使用此控制器控制整个图表。例如:

  • 为任务图设置新的目标滞后。

    ALTER DYNAMIC TABLE controller SET
      TARGET_LAG = <new_target_lag>
    
    Copy
  • 手动刷新任务图。

    ALTER DYNAMIC TABLE controller REFRESH
    
    Copy

关于克隆动态表管道

在同一克隆命令中克隆动态表管道的所有元素,以避免重新初始化管道。您可以通过在同一架构或数据库中整合管道的所有元素(例如基表、视图和动态表)来做到这一点。有关更多信息,请参阅 动态表的已知限制

使用瞬态动态表降低存储成本

瞬态 动态表可随着时间的推移可靠地维护数据,并支持数据保留期内的 Time Travel,但不保留超过故障安全期的数据。默认情况下,动态表数据在 故障安全 存储中保留 7 天。对于具有高刷新吞吐量的动态表,这会显著增加存储消耗。因此,只有当动态表的数据不需要与永久表提供的数据保护和恢复处于相同级别时,才应将其变为瞬态表。

您可以使用 CREATE DYNAMIC TABLE 语句创建瞬态动态表,或将现有动态表克隆到瞬态动态表。

动态表刷新的最佳实践

使用专用仓库进行刷新

动态表需要虚拟仓库来执行刷新。为了清晰了解与动态表管道相关的成本,您应使用专用仓库测试动态表,以便可以隔离归因于动态表的虚拟仓库使用。有关更多信息,请参阅 了解动态表的成本

使用下游滞后

下游滞后指示当其他从属动态表需要刷新时,动态表应刷新。 由于下游滞后易于使用且具备成本效益,因此您应该使用下游滞后作为最佳实践。如果没有下游滞后,管理复杂的动态表链时需要为每个表单独分配目标滞后并管理相关的约束条件,而不仅仅是监控最终表的数据新鲜度。有关更多信息,请参阅 了解目标滞后

设置所有生产动态表的刷新模式

动态表的实际 刷新模式 在创建时确定,此后不可变。如果未显式指定,刷新模式默认为 AUTO,它会根据查询复杂性、不支持的构造、运算符或函数等各种因素选择刷新模式。

要确定适合您用例的最佳模式,请尝试不同的刷新模式和自动建议。要在不同的 Snowflake 版本中保持一致的行为,请在所有生产表上显式设置刷新模式。AUTO 的行为可能会在 Snowflake 版本之间发生变化,这可能会导致在生产管道中使用时性能出现意外变化。

要验证动态表的刷新模式,请参阅 查看动态表刷新模式

优化性能的最佳实践

为了优化动态表的性能,您应该了解系统、尝试各种想法并根据结果进行迭代。例如:

  1. 根据您的成本、数据滞后和响应时间需求,制定改进数据管道的方法。

  2. 实施下列行动:

    1. 从小型固定数据集开始,快速开发查询。

    2. 使用动态数据测试性能。

    3. 缩放数据集以验证它是否满足您的需求。

  3. 根据得到的结果调整工作负载。

  4. 根据需要重复,优先考虑对性能影响最大的任务。

此外,使用下游延迟来高效管理表之间的刷新依赖关系,确保仅在必要时进行刷新。有关详细信息,请参阅 性能文档

选择刷新模式

要确定最适合您用例的模式,请尝试自动建议和具体的刷新模式(完整和增量)。您动态表的最佳模式取决于数据变化量和查询复杂性。此外,使用专用仓库测试不同的刷新模式有助于隔离成本,并根据实际工作负载改善性能调优。

要验证动态表的刷新模式,请参阅 查看动态表刷新模式

  • AUTO 刷新模式:系统默认尝试应用增量刷新。当 增量刷新不受支持 或预计无法良好运行时,动态表会自动选择完全刷新。

    • 为了保持一致的行为,请在所有生产表上显式设置刷新模式。AUTO 的行为可能会在 Snowflake 版本之间发生变化,这可能会导致在生产管道中使用时性能出现意外变化。

  • 增量刷新:仅使用自上次刷新以来的更改来更新动态表,非常适合频繁进行小更新的大型数据集。

    • 最适合与增量刷新兼容的查询(例如,SELECTWHEREGROUPBY 中的确定性函数、简单联接和基本表达式)。如果存在不受支持的功能,并且刷新模式设置为增量,Snowflake 将无法创建动态表。

    • 使用增量刷新优化性能的一个关键做法是将更改量限制为源数据的 5% 左右,并按分组键对数据进行聚类以减少处理开销。

    • 考虑某些操作组合(例如许多联接基础上的聚合)可能无法有效运行。

  • 完全刷新:重新处理整个数据集并使用完整的查询结果更新动态表。 用于复杂查询或有重大数据更改而需要完全更新的情况。

    • 当由于复杂的查询、非确定性函数或数据的重大更改而不支持增量刷新时很有用。

有关更多信息,请参阅 刷新模式如何影响动态表性能

完全刷新性能

完全刷新动态表执行时与 CREATE TABLE ...AS SELECT(也称为 CTAS) 类似。可以对它们进行优化,就像优化任何其他 Snowflake 查询一样。

增量刷新性能

为了帮助您的动态表实现最佳的增量刷新性能,请执行以下操作:

  • 保持源表和动态表的刷新之间的更改最小,理想情况下为小于总数据集的 5%。

  • 考虑修改的微分区数量,而不仅仅是行数。增量刷新必须完成的工作量与这些微分区的大小成正比,而不仅仅与发生更改的行成正比。

  • 最大限度地减少查询中的联接、GROUP BYs 和 PARTITION BYs 等分组操作。将大型公用表表达式 (CTEs) 分解为较小的部分,并为每个部分创建一个动态表。避免对单个动态表使用过多的聚合或联接。

  • 通过将表更改与查询键(例如联接、GROUP BYs、PARTITION BYs)保持一致,确保数据局部性。如果您的表不是由这些键自然聚类,请考虑启用 自动聚类

语言: 中文