物化视图与投影
用户常常会问他们何时应该使用物化视图而不是投影。本文将探讨两者之间的主要区别,以及为什么在某些情况下您可能更倾向于选择其中一个。
主要区别总结
下表总结了物化视图和投影在各个考虑方面的主要区别。
方面 | 物化视图 | 投影 |
---|---|---|
数据存储和位置 | 将结果存储在一个独立的、明确的目标表中,作为对源表插入的触发器。 | 投影创建优化的数据布局,这些布局物理上与主表数据存储在一起,对用户而言是不可见的。 |
更新机制 | 在源表的INSERT 上同步操作(对于增量物化视图)。注意:它们还可以使用可刷新的物化视图进行计划。 | 在向主表插入时异步更新。 |
查询交互 | 使用物化视图时需要直接查询目标表,这意味着用户在编写查询时需要注意物化视图的存在。 | 投影由 ClickHouse 的查询优化器自动选择,在透明性方面,用户不需要修改其查询以利用具有投影的表。从版本 25.6 开始,也可以按多个投影进行过滤。 |
处理UPDATE / DELETE | 不会自动响应源表上的UPDATE 或DELETE 操作,因为物化视图对源表没有了解,仅充当插入触发器。这样可能导致源表和目标表之间的数据过时,并需要解决方法或定期完全刷新。(通过可刷新的物化视图)。 | 默认情况下,与DELETED 行不兼容(尤其是轻量级删除)。lightweight_mutation_projection_mode (v24.7+)可以启用兼容性。 |
JOIN 支持 | 是的。可刷新的物化视图可用于复杂的非规范化。增量物化视图仅在最左侧表插入时触发。 | 否。在投影定义中不支持JOIN 操作以过滤物化数据。 |
定义中的 WHERE 子句 | 是的。可以包括 WHERE 子句以在物化之前过滤数据。 | 否。在投影定义中不支持 WHERE 子句以过滤物化到投影本身的数据。 |
链接能力 | 是的,一个物化视图的目标表可以是另一个物化视图的源,支持多阶段管道。 | 否。投影不能链式使用。 |
适用的表引擎 | 可与各种源表引擎一起使用,但目标表通常属于 MergeTree 家族。 | 仅适用于 MergeTree 家族的表引擎。 |
故障处理 | 数据插入过程中的故障意味着目标表中的数据丢失,从而导致潜在的不一致性。 | 故障在后台静默处理。查询可以无缝混合物化部分和非物化部分。 |
操作开销 | 需要明确的目标表创建,并且通常需要手动填充。管理UPDATE /DELETE 的一致性增加了复杂性。 | 投影是自动维护并保持同步的,通常具有较低的操作负担。 |
FINAL 查询兼容性 | 通常兼容,但通常需要在目标表上使用 GROUP BY 。 | 不支持 FINAL 查询。 |
延迟物化 | 是的。 | 在使用物化特性时监控投影兼容性问题。您可能需要设置 query_plan_optimize_lazy_materialization = false |
并行副本 | 是的。 | 否。 |
optimize_read_in_order | 是的。 | 是的。 |
轻量级更新和删除 | 是的。 | 否。 |
比较物化视图和投影
何时选择物化视图
您应该考虑使用物化视图的情况:
- 处理实时 ETL 和多阶段数据管道:您需要执行复杂的变换、聚合,或在数据到达时进行路由,可能通过链式视图跨多个阶段。
- 您需要复杂的非规范化:您需要将来自多个源(表、子查询或字典)的数据预先连接到一个单一的、针对查询优化的表中,尤其是在可以接受使用可刷新的物化视图进行定期完全刷新的情况下。
- 您希望明确的模式控制:您需要一个独立、独特的目标表,其具有自己的模式和引擎,供预计算结果使用,为数据建模提供更大的灵活性。
- 您希望在摄取时进行过滤:您需要在数据物化之前过滤数据,从而减少写入目标表的数据量。
何时避免物化视图
您应该考虑避免使用物化视图的情况:
- 源数据频繁更新或删除:如果没有额外的策略来处理源表和目标表之间的一致性,增量物化视图可能会变得过时和不一致。
- 简单和自动优化更可取:如果您希望避免管理单独的目标表。
何时选择投影
您应该考虑使用投影的情况:
- 针对单一表优化查询:您的主要目标是通过提供替代排序顺序,加速对单个基础表的查询,优化不属于主键的列上的过滤,或为单个表预计算聚合。
- 您希望查询透明性:您希望查询针对原始表而不进行修改,依赖 ClickHouse 为给定查询选择最佳数据布局。
何时避免投影
您应该考虑避免使用投影的情况:
- 需要复杂的数据转换或多阶段 ETL:投影在其定义中不支持
JOIN
操作,无法更改以建立多步骤管道,并且无法处理某些 SQL 特性,如窗口函数或复杂的CASE
语句。因此,它们不适合复杂的数据转换。 - 需要明确过滤物化数据:投影在其定义中不支持
WHERE
子句以过滤进入投影本身的数据。 - 使用非 MergeTree 表引擎:投影仅适用于使用
MergeTree
家族引擎的表。 FINAL
查询是必需的:投影不支持FINAL
查询,这在某些情况下用于去重。- 您需要 并行副本,因为投影不支持并行副本。
总结
物化视图和投影都是您优化查询和变换数据的强大工具,一般来说,我们建议不要将它们视为非此即彼的选择。相反,它们可以以互补的方式使用,以便充分利用您的查询。因此,在 ClickHouse 中选择物化视图和投影真正取决于您的特定用例和访问模式。
作为一般的经验法则,当您需要将来自一个或多个源表的数据聚合到目标表中或在大规模上执行复杂的变换时,您应该考虑使用物化视图。物化视图非常适合将昂贵的聚合工作从查询时间转移到插入时间。它们非常适合每日或每月汇总、实时仪表盘或数据摘要。
另一方面,当您需要优化针对的数据过滤的列,而这些列不属于表的主键时,您应该使用投影,因为主键决定了数据在磁盘上的物理顺序。特别是在无法更改表的主键时,或者当您的访问模式比主键能够容纳的范围更广泛时,投影非常有用。