具体化视图的增量刷新

本文概述了具体化视图增量刷新的语义和要求,并标识支持增量刷新的 SQL 操作、关键字和子句。 它包括讨论增量刷新和完全刷新之间的差异,并包括有关在具体化视图和流式处理表之间进行选择的建议。

使用无服务器管道对具体化视图运行更新时,可以增量刷新许多查询。 增量刷新通过检测用于定义具体化视图的数据源中的更改并增量计算结果来节省计算成本。

增量刷新需要无服务器管道

具体化视图的增量刷新需要无服务器管道。

Databricks SQL 中定义的具体化视图的刷新操作始终使用无服务器管道运行。

对于使用 Delta Live Tables 管道定义的具体化视图,必须将管道配置为使用无服务器。 请参阅配置无服务器增量实时表管道

具体化视图的刷新语义是什么?

具体化视图保证与批处理查询等效的结果。 例如,请考虑以下聚合查询:

SELECT account_id,
  COUNT(txn_id) txn_count,
  SUM(txn_amount) account_revenue
FROM transactions_table
GROUP BY account_id

使用任何 Azure Databricks 产品运行此查询时,将使用批处理语义计算结果,以聚合源 transactions_table中的所有记录,这意味着在一个操作中扫描和聚合所有源数据。

注意

如果数据源在上次查询运行后未更改,某些 Azure Databricks 产品会在会话内或跨会话自动缓存结果。 自动缓存行为不同于具体化视图。

以下示例将此批处理查询转换为具体化视图:

CREATE OR REFRESH MATERIALIZED VIEW transation_summary AS
SELECT account_id,
  COUNT(txn_id) txn_count,
  SUM(txn_amount) account_revenue
FROM transactions_table
GROUP BY account_id

刷新具体化视图时,计算结果与批处理查询语义相同。 此查询是可增量刷新的具体化视图的示例,这意味着刷新操作会尽力尝试仅处理源 transactions_table 中的新数据或更改的数据以计算结果。

具体化视图的数据源注意事项

虽然你可以针对任何数据源定义具体化视图,但并非所有数据源都非常适合具体化视图。 请考虑以下注意事项和建议:

重要

具体化视图尽力尝试增量刷新支持操作的结果。 数据源中的某些更改需要完全刷新。

即使定义具体化视图的查询支持增量刷新,具体化视图的所有数据源都应可靠,以完全刷新语义。

  • 对于完全刷新成本过高的查询,请使用流式处理表保证完全一次处理。 示例包括非常大的表。
  • 如果只应处理一次记录,请不要针对数据源定义具体化视图。 请改用流式处理表。 示例包括:
    • 不保留数据历史记录的数据源,例如 Kafka。
    • 引入操作,例如使用自动加载程序从云对象存储引入数据的查询。
    • 打算在处理后删除或存档数据但需要在下游表中保留信息的任何数据源。 例如,计划删除早于特定阈值的记录的日期分区表。
  • 并非所有数据源都支持增量刷新。 以下数据源支持增量刷新:
    • Delta 表,包括由 Delta Lake 支持的 Unity 目录托管表和外部表。
    • 具体化视图。
    • 流式处理表,包括操作的目标 APPLY CHANGES INTO
  • 某些增量刷新操作需要在查询的数据源上启用行跟踪。 行跟踪只是 Delta 表支持的 Delta Lake 功能,其中包括具体化视图、流式处理表和 Unity 目录托管表。 请参阅对 Delta 表使用行跟踪

优化具体化视图

为了获得最佳性能,Databricks 建议在所有具体化视图源表上启用以下功能:

具体化视图的刷新类型

具体化视图的刷新是完整视图或增量视图。 对于所有操作,增量刷新和完全刷新的结果相同。 Azure Databricks 运行成本分析,以确定对数据源的更改是否需要完全刷新。

若要确定使用的更新的刷新类型,请参阅 “确定更新的刷新类型”。

完全刷新

完全刷新通过重新处理源中可用的所有数据来覆盖具体化视图中的结果。 所有具体化视图可能会在任何给定更新上完全刷新,具体取决于数据源的更改方式。

可以选择性地强制完全刷新。 对于使用 Databricks SQL 定义的具体化视图,请使用以下语法:

REFRESH MATERIALIZED VIEW mv_name FULL

对于增量实时表管道中定义的具体化视图,可以选择对所选数据集或管道中的所有数据集运行完全刷新。 请参阅 增量实时表如何更新表和视图

重要

当完全刷新针对由于数据保留阈值或手动删除而删除记录的数据源运行时,已删除的记录不会反映在计算结果中。 如果数据在源中不再可用,则可能无法恢复旧数据。

注意

可以选择通过将表属性 pipelines.reset.allowed 设置为 false 来禁用表的完全刷新。

增量刷新

增量刷新在上次刷新后处理基础数据中的更改,然后将该数据追加到表中。 根据基表和包含的操作,某些类型的具体化视图只能进行增量刷新。

只有使用无服务器管道更新的具体化视图才能使用增量刷新。 不使用无服务器管道的具体化视图始终会完全刷新。

使用 SQL 仓库或无服务器 Delta Live Tables 管道创建具体化视图时,如果支持其查询,它们会自动以增量方式刷新。 如果查询包含增量刷新不支持的表达式,则会执行完全刷新,这可能会导致额外的成本。

支持具体化视图增量刷新

下表列出了 SQL 关键字或子句对增量刷新的支持。

重要

某些关键字和子句要求对查询的数据源启用行跟踪。 请参阅对 Delta 表使用行跟踪

这些关键字和子句在下表中用星号进行标记。

SQL 关键字或子句 增量刷新支持
SELECT 表达式* 是的,支持包括确定性的内置函数和不可变用户定义函数 (UDF) 的表达式。
GROUP BY
WITH 是,支持通用表表达式。
UNION ALL*
FROM 支持的基表包括增量表、具体化视图和流式处理表。
WHERE, HAVING* 支持筛选器子句,例如 WHEREHAVING
INNER JOIN*
LEFT OUTER JOIN*
FULL OUTER JOIN*
RIGHT OUTER JOIN*
OVER 是的。 PARTITION_BY 必须为窗口函数的增量化指定列。
QUALIFY
EXPECTATIONS 否。 使用预期的具体化视图始终完全刷新。

注意

不支持非确定性函数,例如 CURRENT_TIMESTAMP

确定更新的刷新类型

为了优化具体化视图刷新的性能,Azure Databricks 使用成本模型来选择用于刷新的技术。 下表介绍了这些技术:

方法 增量刷新? 说明
FULL_RECOMPUTE 已完全重新计算具体化视图
NO_OP 不适用 未更新具体化视图,因为未检测到基表的更改。
ROW_BASEDPARTITION_OVERWRITE 具体化视图已使用指定技术以增量方式刷新。

要确定使用的技术,请查询 Delta Live Tables 事件日志,其中 event_typeplanning_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> 替换为具体化视图的完全限定名称,包括目录和架构。

请参阅什么是增量实时表事件日志?