本文概述了具体化视图增量刷新的语义和要求,并确定了支持增量刷新的 SQL 操作、关键字和子句。 它包括对增量刷新和整体刷新之间差异的讨论,并包含有关在具体化视图和流式处理表之间进行选择的建议。
使用无服务器管道对具体化视图运行更新时,许多查询可以进行增量刷新。 增量刷新通过检测用于定义具体化视图的数据源中的更改并增量计算结果来节省计算成本。
刷新操作在无服务器计算环境中运行
刷新操作在无服务器管道上运行,无论该操作是在 Databricks SQL 中定义的,还是通过 Lakeflow 声明性管道定义的。
对于使用 Databricks SQL 定义的具体化视图,你的工作区无需启用无服务器 Lakeflow 声明性管道。 刷新将自动使用无服务器管道。
对于使用 Lakeflow 声明性管道定义的具体化视图,你必须将管道配置为使用无服务器。 请参阅 配置无服务器管道。
具体化视图的刷新语义是什么?
具体化视图保证与批处理查询等效的结果。 例如,考虑以下聚合查询:
SELECT account_id,
COUNT(txn_id) txn_count,
SUM(txn_amount) account_revenue
FROM transactions_table
GROUP BY account_id
当你使用任何 Azure Databricks 产品运行此查询时,结果是使用批处理语义计算的,以聚合源 transactions_table 中的所有记录,这意味着所有源数据在一个操作中被扫描和聚合。
Note
如果数据源在上次查询运行后未发生更改,某些 Azure Databricks 产品会在会话内或跨会话自动缓存结果。 自动缓存行为与具体化视图不同。
以下示例将此批处理查询转换为具体化视图:
CREATE OR REPLACE MATERIALIZED VIEW transaction_summary AS
SELECT account_id,
COUNT(txn_id) txn_count,
SUM(txn_amount) account_revenue
FROM transactions_table
GROUP BY account_id
当你刷新具体化视图时,计算结果与批处理查询语义相同。 此查询是可以进行增量刷新的具体化视图示例,这意味着刷新操作会尽最大努力仅处理源 transactions_table 中的新数据或已更改数据来计算结果。
具体化视图的数据源注意事项
虽然你可以针对任何数据源定义具体化视图,但并非所有数据源都适合具体化视图。 请考虑以下注意事项和建议:
Important
具体化视图会尽力尝试以增量方式为支持的操作刷新结果。 数据源中的某些更改需要整体刷新。
具体化视图的所有数据源都应能够适应整体刷新语义,即使定义具体化视图的查询支持增量刷新时也是如此。
- 对于整体刷新成本过高的查询,应使用流式处理表,确保精确的一次性处理。 示例包括非常大的表。
- 如果记录应仅处理一次,则不要针对数据源定义具体化视图。 改用流式处理表。 示例包括以下内容:
- 不保留数据历史记录的数据源,例如 Kafka。
- 引入操作,例如使用自动加载程序从云对象存储引入数据的查询。
- 任何你计划在处理后删除或存档数据但需要在下游表中保留信息的数据源。 例如,日期分区表,其中需要计划删除早于特定阈值的记录。
- 并非所有数据源都支持增量刷新。 以下数据源支持增量刷新:
- 增量表,包括 Unity Catalog 托管表和由 Delta Lake 支持的外部表。
- 具体化视图。
- 流式处理表,包括
AUTO CDC ... INTO操作的目标。
- 某些增量刷新操作要求在查询的数据源上启用行跟踪。 行跟踪是仅 Delta 表支持的 Delta Lake 功能,其中包括具体化视图、流式处理表和 Unity Catalog 托管表。 请参阅对 Delta 表使用行跟踪。
优化具体化视图
为获得最佳性能,Databricks 建议在所有具体化视图源表上启用以下功能:
可以在创建时设置这些功能,或者稍后通过 ALTER TABLE 语句进行设置。 例如:
ALTER TABLE <table-name> SET TBLPROPERTIES (
delta.enableDeletionVectors = true,
delta.enableRowTracking = true,
delta.enableChangeDataFeed = true);
具体化视图的刷新类型
更新具体化视图时,可以指定刷新或完全刷新。
- 刷新会尝试执行增量刷新,但会根据需要对数据进行完全重新计算。 仅当连接到的计算是无服务器时,增量刷新才可用。
- 完全刷新始终重新计算具体化视图的所有输入,并重置所有检查点。
要确定更新使用的刷新类型,请参阅确定更新的刷新类型。
默认刷新
无服务器尝试执行 增量刷新时的具体化视图的默认刷新。 增量刷新会处理上次刷新后基础数据中的更改,然后将该数据追加到表中。 根据基表和包含的操作,某些类型的具体化视图只能进行增量刷新。 如果无法进行增量刷新,或者连接的计算是经典计算而不是无服务器刷新,则会执行完整的重新计算。
增量刷新和完整重新计算的输出相同。 Azure Databricks 运行成本分析,在增量刷新和完全重新计算之间选择更便宜的选项。
只有使用无服务器管道更新的具体化视图才能使用增量刷新。 不使用无服务器管道的具体化视图始终完全重新计算。
使用 SQL 仓库或无服务器 Lakeflow 声明性管道创建具体化视图时,Azure Databricks 会增量刷新这些视图(如果支持查询)。 如果查询使用不受支持的表达式,Azure Databricks 会改为运行完全重新计算,这可能会增加成本。
要确定更新使用的刷新类型,请参阅确定更新的刷新类型。
完全刷新
完全刷新通过清除表和检查点来覆盖具体化视图中的结果,并重新处理源中可用的所有数据。
若要对使用 Databricks SQL 定义的具体化视图执行完全刷新,请使用以下语法:
REFRESH MATERIALIZED VIEW mv_name FULL
对于在 Lakeflow 声明性管道中定义的具体化视图,你可以选择对管道中的选定数据集或所有数据集运行整体刷新。 请参阅管道刷新语义。
Important
当针对所含记录因数据保留阈值被删除或被手动删除的数据源运行整体刷新时,计算结果中不会反映删除的记录。 如果数据在源中不再可用,则可能无法恢复旧数据。 这也可能会更改源数据中不再存在的列的架构。
具体化视图增量刷新支持
下表列出了 SQL 关键字或子句对增量刷新的支持。
| SQL 关键字或子句 | 增量刷新支持 |
|---|---|
SELECT 表达式* |
是,支持包括确定性内置函数和不可变用户定义函数 (UDF) 在内的表达式。 |
GROUP BY |
Yes |
WITH |
是,支持通用表表达式。 |
UNION ALL* |
Yes |
FROM |
受支持的基表包括 Delta 表、具体化视图和流式处理表。 |
WHERE, HAVING* |
支持筛选器子句,例如 WHERE 和 HAVING。 |
INNER JOIN* |
Yes |
LEFT OUTER JOIN* |
Yes |
FULL OUTER JOIN* |
Yes |
RIGHT OUTER JOIN* |
Yes |
OVER |
Yes. 窗口函数的增量处理必须指定 PARTITION_BY 列。 |
QUALIFY |
Yes |
EXPECTATIONS |
可以,可以增量刷新包含预期的具体化视图。 但是,对于以下情况,不支持增量刷新:
|
| 非确定性函数 | 子句中 WHERE 支持非确定性时间函数。 这包括函数,例如 current_date(), current_timestamp()和 now()。 不支持其他非确定性函数。 |
| 非Delta源 | 不支持卷、外部位置和国外目录等源。 |
确定更新的刷新类型
为了优化具体化视图刷新的性能,Azure Databricks 使用成本模型来选择用于刷新的技术。 下表介绍了这些技术:
| Technique | 增量刷新? | Description |
|---|---|---|
FULL_RECOMPUTE |
No | 已完全重新计算具体化视图 |
NO_OP |
不適用 | 未更新具体化视图,因为未检测到基表的更改。 |
任一项:
|
Yes | 具体化视图使用指定的技术以增量方式刷新。 |
要确定使用的技术,查询 Lakeflow 声明性管道事件日志,其中 event_type 为 planning_information:
SELECT
timestamp,
message
FROM
event_log(TABLE(<fully-qualified-table-name>))
WHERE
event_type = 'planning_information'
ORDER BY
timestamp desc;
将 <fully-qualified-table-name> 替换为具体化视图的完全限定名称,包括目录和架构。
此命令的示例输出:
-
- 时间戳
- 消息
-
2025-03-21T22:23:16.497+00:00Flow 'sales' has been planned in :re[LDP] to be executed as ROW_BASED.
请参阅 Lakeflow 声明性管道事件日志。