刷新模式如何影响动态表性能

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

小技巧

要确定适合您用例的最佳模式,请尝试不同的刷新模式和自动建议。要在不同的 Snowflake 版本中保持一致的行为,您应该在所有动态表上显式设置刷新模式。

完整刷新模式性能

完整刷新运行查询并使用结果覆盖动态表。您可以 像其他 Snowflake 查询 一样优化整体刷新性能。请注意,成本包括运行查询和插入结果,因此不要直接与仅运行查询进行比较。

增量刷新模式性能

增量刷新计算查询结果中的更改,并将其合并到动态表中。这是一个强大的功能,但它在某些条件下效果最好。

以下部分解释了工作负载适合增量刷新需满足的条件。如果您的工作负载不符合这些部分中描述的条件,请尝试整体刷新模式以提升效率。

备注

随着时间的推移,随着对增量刷新查询和性能的支持的改进,本文档中的建议可能会发生变化。

了解增量刷新性能

在增量刷新中,大部分工作通常用于计算动态表中的更改。这取决于查询,可能相当复杂。一个常见的误解是增量刷新只扫描源表中的更改,而不是源表本身。这可能导致误解为增量刷新只应执行与更改的源数据量成比例的工作,但事实并非如此。实际上,增量刷新通常需要直接扫描源表。

例如,想象一个查询在表 A 和表 B 之间进行内部联接。如果向表 A 插入一行,它必须与表 B 联接,以计算查询中的更改。A 中的单行可以与 B 中的多行联接,与源中的变更相比,会造成很多额外的工作。

这种额外的工作可能需要利用各种运算符来完成。因此,增量刷新不执行新的工作,而是跳过已经完成的工作。决定跳过什么内容十分耗费精力,,特别是复杂的查询,不同的运算符可能会以不同的方式跳过工作

通常,变更的大小和局部性会影响可以跳过多少工作。

大小如何影响增量刷新性能

影响增量刷新性能的最重要因素是源数据变更的大小。

举一个极端的例子,想想从源中删除所有数据的工作量 – 增量刷新必须读取每个已删除的行,这会使速度变慢。相比之下,整体刷新只涉及一个空表,,所以它速度更快。

类似的减速也可能发生在不太极端的情况下。良好工作负载的一个良好准则是将源或目标中的变更控制在行数的 5% 以下。

局部性如何影响增量刷新性能

影响增量刷新的第二个最重要因素是 局部性,它是指不同维度上数据或操作的相关程度。

例如,如果您有一个包含时间戳列的表,并且始终在该列中插入包含当前时间的行,那么您的工作负载在插入顺序和时间戳列之间具有很强的局部性。

局部性能够以各种形式显示,但少数形式对于增量刷新特别重要。在以下任一领域改进局部性可提升增量刷新的性能,尽管有时不太可能所有三个类别都具有强局部性。

局部性领域

描述

群集密钥和分区密钥之间的局部性。

在动态表定义中执行分区操作时,根据这些分区密钥对基础源进行群集是有益的。

例如,如果您使用 ID 联接两个表,如果表按其 ID 列进行群集,则对于增量刷新性能更有益。

分区密钥或分组密钥与源变更之间的局部性。

理想情况下,对源的变更应主要涉及包含附近行的分组。

例如,如果您插入包含当前时间戳的行,由于密钥和源变更之间的强局部性,按小时分组可能会运行良好。但是,如果插入的行包含出现在表中许多其他行中的列值,则按该列分组会导致增量刷新性能较差。

目标表变更和群集之间的局部性。

当增量刷新将更改应用于动态表时,将针对动态表的当前状态加入更新和删除。

如果变更与动态表上的群集一致,则此联接的性能会更好。例如,如果刷新仅更新最近插入的行,则它们与表的群集非常一致。

有关 Snowflake 表的存储方式的信息,请参阅 了解 Snowflake 表结构。要管理表上的群集,请使用 自动聚类

单个运算符增量刷新的性能预期

下表显示了单个运算符增量刷新的近似性能预期。性能是相对于整体刷新来衡量的,并且假设只有 5% 的行发生了变更。

运算符

性能提升

SELECT

10 倍

WHERE

10 倍

FROM

10 倍

UNION ALL

10 倍

标量汇总

10 倍

对于受局部性影响的运算符,该表显示了具有良好局部性和较差局部性的性能预期。请注意,对于某些运算符来说,较差局部性可能导致比整体刷新更糟糕的性能。

运算符

局部性

性能提升

GROUP BY

良好

5 倍

GROUP BY

较差

1/3 倍

DISTINCT

良好

5 倍

DISTINCT

较差

1/4 倍

OVER

良好

2-5 倍

OVER

较差

1/5 倍

INNER JOIN

良好

10 倍

INNER JOIN

较差

2 倍

OUTER JOIN

良好

3 倍

OUTER JOIN

较差

0.1 倍

有关更多信息,请参阅 运算符如何增量刷新

优化复杂动态表的增量刷新模式性能

动态表通常包含多个运算符,因此难以预测增量刷新的性能。本部分探讨了如何应对这一挑战,并给出了一些增强复杂动态表性能的技巧。

当涉及多个运算符时,增量刷新通过分别处理每个运算符来计算更改,将其变为查询计划的片段,查询计划可以基于其输入计算更改。对于每个输入,此新片段可以在变更之前、变更之后或仅将变更本身请求输入。通过将此过程应用于原始查询中的每个运算符,您将获得一个新的查询计划,该计划将混合使用变更扫描和完整表扫描计算更改。该计划由 Snowflake 的查询优化器优化,并像任何其他查询一样执行。

当复杂的增量刷新性能不佳时,通常是因为变更次数太多或局部性较差导致。

在复杂的查询中,每个运算符都关注其输入的变更量和局部性。然而,这些输入是其他运算符的输出,因此数据的数量和局部性会随着运算符之间的移动而发生变化。

以下是一些常见的场景和解决这些问题的建议:

场景

建议

跨多列联接表时,不能同时对所有列使用 CLUSTER BY。

根据频繁变更的密钥优先对较大的表进行群集。例如,在具有大维度表的星级架构中,重点关注维度表的群集。

考虑为同一数据集创建多个副本,每个副本由不同的密钥进行群集,并在相关上下文中使用它们。

当有 GROUP BY 或 OVER 以上时,会有多个联接。

确保源表通过分组/分区密钥进行群集,并考虑将联接和聚合拆分为两个独立的动态表。

请注意,外部联接与聚合的交互较差。

语言: 中文