物化视图#

物化视图简介

物化视图是一个存储预计算结果集的实体,其计算逻辑由创建时的 SELECT 语句定义。与仅存储计算逻辑的视图不同,物化视图在 OushuDB 数据库中可以通过预计算好的结果集加速复杂查询。当查询频繁或复杂,尤其是在处理代价非常昂贵的聚合、投影和选择操作时,经过物化视图重写的语句会显著高于原始语句的执行效率。因此,物化视图非常适合需要经过聚合或复杂计算大型数据集的快速访问。

备注

物化视图旨在提高由常见重复查询模式组成的工作负载的查询性能。但是,物化中间结果会产生额外的空间存储成本。因此,在创建任何物化视图之前,应考虑频繁重复使用这些结果所节省的计算开销是否能抵消这些成本。

物化视图基本操作#

物化视图基本操作

1. 创建物化视图

创建物化视图的语法参考创建物化视图

2. 修改物化视图

修改物化视图的语法参考修改物化视图

3. 删除物化视图

删除物化视图的语法参考删除物化视图

物化视图刷新调度#

物化视图刷新调度简介

物化视图调度用于管理和优化视图的数据刷新,通过灵活的参数配置,可以满足不同的业务需求。主要功能包括:

刷新方法:通过 REFRESH_METHOD 设置刷新模式,包括自动选择(AUTO)、全量刷新(FULL)等选项。

刷新时机:通过 REFRESH_TIME 定义刷新触发条件,例如按计划刷新(FOLLOW_SCHEDULE)或数据变更后立即刷新(ON_COMMIT)。

计划刷新:支持通过 SCHEDULE_START 和 SCHEDULE_INTERVAL 设置定时刷新策略,并分配资源队列(RESOURCE_QUEUE)以保证刷新效率。

查询优化:通过 ENABLE_REWRITE 参数启用透明查询重写,实现查询性能加速。

参数配置可以参考创建物化视图可选参数

物化视图查询重写#

物化视图查询重写简介

查询重写是指在对基表进行查询时, 如果基表上创建有物化视图,数据库系统自动判断是否可以使用物化视图中的预计算结果处理查询。通过重写查询,可以提高查询性能,降低响应时间,并有效利用存储资源。这一过程通常涉及分析查询的结构、合适的刷新策略,以确保物化视图能够为查询提供最佳的支持。

物化视图查询重写触发流程

1. 创建物化视图

分析需要加速查询的 SQL 结构,选取目标 SQL部分完整 SELECT-SQL 结构作为创建物化视图的计算结构进行创建。

create table t(id int);
create materialized view mv as select * from t;

2. 更新物化视图存储数据

通过手动执行 REFRESH MATERIALIZED VIEW SQL 命令或配置物化视图定时刷新策略,刷新物化视图使其重新计算最新数据。

备注

未及时刷新数据可能导致使用过时数据参与计算

refresh materialized view mv;

3. 查询自动匹配重写

执行需要加速查询的 SQL,用户可通过 EXPLAIN 命令检查 MatviewRewrie: ON 输出以检查当前查询是否使用物化视图。

explain select * from t;

                              QUERY PLAN
----------------------------------------------------------------------------
Gather Motion 4:1  (slice1; segments: 4)  (cost=0.00..1.03 rows=1 width=4)
Output: id
->  Seq Scan on public.mv  (cost=0.00..1.01 rows=1 width=4)
      Output: id
Optimizer: Postgres-based planner
NewExecutor: ON
MatviewRewrite: ON
(7 rows)

物化视图查询相关参数

参数名称

参数类型

参数默认值

参数介绍

enable_matview_rewrite

bool

on

物化视图查询重写功能开关

matview_rewrite_blacklist

char*

null

存在于该参数中的物化视图不会参与查询重写。

matview_rewrite_allow_defy_order

bool

on

物化视图计算结构中的 Order By 部分在参与查询重写时不会对结果集有影响,因此默认的查询重写匹配逻辑会忽略物化视图的 Order By 结构进行匹配,当参数为关闭时,将对 Order By 结构进行严格匹配

物化视图查询重写最佳实践

物化视图在以下情况下被创建时会有更好的作用

  • 相对于基础表(定义视图的表),查询结果只包含少量行和(或)列。

  • 查询结果包含需要大量处理的结果,包括

  1. 半结构化数据分析

  2. 需要长时间计算的聚合

  3. 查询外部表

  4. 物化视图的基本表不经常变化

物化视图查询重写示例

  1. 对包含带聚合语句的SQL查询重写

create materialized view mv_agg as select sum(id) from t group by id;

explain select sum(id) from t group by id;

                              QUERY PLAN
---------------------------------------------------------------------------------
Gather Motion 4:1  (slice1; segments: 4)  (cost=0.00..16.00 rows=1000 width=16)
Output: sum, sum
->  Seq Scan on public.mv_agg  (cost=0.00..3.50 rows=250 width=16)
      Output: sum, sum
Optimizer: Postgres-based planner
NewExecutor: ON
MatviewRewrite: ON
(7 rows)
  1. 对包含WHERE语句的SQL查询重写

create materialized view mv_where as select id from t where id = 1;

explain select id from t where id = 1;

                              QUERY PLAN
----------------------------------------------------------------------------
Gather Motion 4:1  (slice1; segments: 4)  (cost=0.00..1.03 rows=1 width=4)
Output: id
->  Seq Scan on public.mv_where  (cost=0.00..1.01 rows=1 width=4)
      Output: id
Optimizer: Postgres-based planner
NewExecutor: ON
MatviewRewrite: ON
(7 rows)
  1. 对包含子查询语句的SQL查询重写

create materialized view mv_subquery as select id from t where id = 100;

explain select * from (select id from t where id = 100) subquery;

                        QUERY PLAN
----------------------------------------------------------------------------
Gather Motion 4:1  (slice1; segments: 4)  (cost=0.00..1.03 rows=1 width=4)
Output: mv_subquery.id
->  Seq Scan on public.mv_subquery  (cost=0.00..1.01 rows=1 width=4)
      Output: mv_subquery.id
Optimizer: Postgres-based planner
NewExecutor: ON
MatviewRewrite: ON
(7 rows)

物化视图查询功能约束

  • 不支持包含 UDF (user-defined function) 的查询语句

  • 不支持包含 RECURSIVE CTE 的查询语句

  • 不支持包含 LIMIT / OFFSET / FETCH 的查询语句

  • 不支持包含 FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } 的查询语句

  • 不支持包含 LATERAL 的查询语句

  • 不支持包含 Window Function 的查询语句

  • 不支持包含随机函数(例如 random()now() 等)的查询语句

  • 不支持对已有查询语句做 FROM / JOIN 拼接

  • 不支持对已有查询句语做 OR 条件拼接