可刷新物化视图
可刷新的物化视图 在概念上与传统 OLTP 数据库中的物化视图类似,存储指定查询的结果以便于快速检索,从而减少重复执行资源密集型查询的需要。与 ClickHouse 的 增量物化视图 不同,这需要定期在完整数据集上执行查询 - 其结果存储在目标表中以供查询。理论上,这个结果集应该小于原始数据集,从而使后续查询能够更快地执行。
下图说明了可刷新的物化视图是如何工作的:

您还可以查看以下视频:
何时使用可刷新的物化视图?
ClickHouse 的增量物化视图功能强大,并且通常比可刷新的物化视图所使用的方法更具扩展性,特别是在需要对单个表执行聚合操作的情况下。通过仅在每个数据块插入时计算聚合,并在最终表中合并增量状态,查询仅在数据的一个子集上执行。这种方法可扩展到潜在的 PB 级数据,通常是首选方法。
然而,有些用例并不需要或不适合这种增量处理。一些问题与增量方法不兼容或不需要实时更新,周期性重建更为合适。例如,您可能希望定期在完整数据集上执行视图的完全重新计算,因为它使用了复杂的连接,而这与增量方法不兼容。
可刷新的物化视图可以运行批处理过程,执行诸如反规范化之类的任务。可以在可刷新的物化视图之间创建依赖关系,使一个视图依赖于另一个视图的结果,并且仅在其完成后执行。这可以替代计划工作流或简单的 DAG,例如 dbt 作业。要了解有关如何在可刷新的物化视图之间设置依赖关系的更多信息,请参见 创建视图 的
Dependencies
部分。
如何刷新可刷新的物化视图?
可刷新的物化视图会在创建时定义的间隔上自动刷新。 例如,以下物化视图每分钟刷新一次:
如果您想强制刷新物化视图,可以使用 SYSTEM REFRESH VIEW
子句:
您还可以取消、停止或启动视图。 有关更多详细信息,请参见 管理可刷新的物化视图 文档。
最近一次刷新可刷新的物化视图是什么时候?
要查找可刷新的物化视图上次刷新的时间,您可以查询 system.view_refreshes
系统表,如下所示:
如何更改刷新频率?
要更改可刷新的物化视图的刷新频率,请使用 ALTER TABLE...MODIFY REFRESH
语法。
完成后,您可以使用 最近一次刷新可刷新的物化视图是什么时候? 查询以检查频率是否已更新:
使用 APPEND
添加新行
APPEND
功能允许您将新行添加到表的末尾,而不是替换整个视图。
此功能的一个用途是在某个时间点捕获值的快照。例如,假设我们有一个 events
表,由来自 Kafka、 Redpanda 或其他流数据平台的消息流填充。
该数据集在 uuid
列中有 4096
个值。我们可以编写以下查询来查找出现总数最高的那些:
假设我们想要每 10 秒捕获一次每个 uuid
的计数,并将其存储在一个名为 events_snapshot
的新表中。 events_snapshot
的模式如下所示:
然后,我们可以创建一个可刷新的物化视图来填充此表:
接下来,我们可以查询 events_snapshot
来获取特定 uuid
随时间变化的计数:
示例
现在让我们看一下如何使用可刷新的物化视图和一些示例数据集。
Stack Overflow
反规范化数据指南 显示了使用 Stack Overflow 数据集反规范化数据的各种技术。我们将数据填充到以下表中: votes
、users
、badges
、posts
和 postlinks
。
在该指南中,我们展示了如何使用以下查询将 postlinks
数据集反规范化到 posts
表中:
我们随后展示了如何一次性将这些数据插入 posts_with_links
表,但在生产系统中,我们希望定期运行此操作。
posts
和 postlinks
表都可能会更新。因此,与其尝试使用增量物化视图实现连接,不如简单地安排此查询在设定的间隔内运行,例如每小时一次,将结果存储在 post_with_links
表中。
这就是可刷新的物化视图可以派上用场的地方,我们可以通过以下查询创建一个:
该视图将立即执行,并在之后的每小时按配置执行,以确保源表的更新得以反映。重要的是,当查询重新运行时,结果集会原子性和透明地更新。
此处的语法与增量物化视图相同,只是我们添加了 REFRESH
子句:
IMDb
在 dbt 和 ClickHouse 集成指南 中,我们使用以下表填充了 IMDb 数据集: actors
、directors
、genres
、movie_directors
、movies
和 roles
。
然后,我们可以编写以下查询来计算每个演员的摘要,按电影出场次数排序。
返回结果的时间不长,但假设我们希望它更快,并且计算成本更低。 假设该数据集也受到持续更新的影响 - 不断有电影上映,新演员和导演也不断涌现。
现在是可刷新的物化视图的时机,所以我们首先为结果创建一个目标表:
现在我们可以定义视图:
该视图将立即执行,并在之后的每分钟按配置执行,以确保源表的更新被反映。我们先前用于获取演员摘要的查询在语法上变得更简单,速度也显着提高!
假设我们添加了一位新演员 “Clicky McClickHouse” 到我们的源数据,恰好出现在许多电影中!
不到 60 秒后,我们的目标表已更新,以反映 Clicky 出色的演技: