pg_ivm模块为PostgreSQL提供增量视图维护(IVM)功能。 该扩展与PostgreSQL 13、14、15、16和17版本兼容。
**增量视图维护(IVM)**是一种使物化视图保持最新的方法,它只计算并应用视图的增量变化,而不像REFRESH MATERIALIZED VIEW
那样从头重新计算内容。当视图只有小部分发生变化时,IVM比重新计算更有效地更新物化视图。
关于视图维护的时机,有两种方法:即时维护和延迟维护。在即时维护中,视图在其基表被修改的同一事务中更新。在延迟维护中,视图在事务提交后更新,例如,在访问视图时,响应用户命令如REFRESH MATERIALIZED VIEW
,或定期在后台更新等。pg_ivm
提供了一种即时维护方式,即当基表被修改时,物化视图立即在AFTER触发器中更新。
我们将支持IVM的物化视图称为增量可维护物化视图(IMMV)。要创建IMMV,你需要使用关系名称和视图定义查询调用create_immv
函数。例如:
SELECT create_immv('myview', 'SELECT * FROM mytab');
这将创建一个名为'myview'的IMMV,定义为SELECT * FROM mytab
。这相当于以下创建普通物化视图的命令:
CREATE MATERIALIZED VIEW myview AS SELECT * FROM mytab;
当创建IMMV时,会自动创建一些触发器,以便在其基表被修改时立即更新视图的内容。
postgres=# SELECT create_immv('m', 'SELECT * FROM t0'); 注意:无法自动在immv "m"上创建索引 详细信息:此目标列表没有包含所有主键列,或此视图不包含DISTINCT子句。 提示:在immv上创建索引以实现高效的增量维护。 create_immv ------------- 3 (1行) postgres=# SELECT * FROM m; i --- 1 2 3 (3行) postgres=# INSERT INTO t0 VALUES (4); INSERT 0 1 postgres=# SELECT * FROM m; -- 自动更新 i --- 1 2 3 4 (4行)
请注意,如果你使用PostgreSQL 17或更高版本,在IMMV的自动维护期间,search_path
会暂时更改为pg_catalog, pg_temp
。
要安装pg_ivm
,请在模块目录中执行以下命令:
make install
如果您是通过rpm或deb安装的PostgreSQL,则需要开发包(例如,postgresql14-devel或postgresql-server-dev-14)。
重要提示: 如果您想在非默认或自定义构建的PostgreSQL上使用
pg_ivm
,请不要忘记设置PG_CONFIG
变量(make PG_CONFIG=...
)或将pg_config
命令的路径添加到PATH
中。更多信息请参阅这里。 然后,执行CREATE EXTENSION命令。
CREATE EXTENSION pg_ivm;
pg_ivm的RPM包可以从PostgreSQL yum仓库获取。详细信息请参阅说明。请注意,我们不是该yum仓库的维护者,其中的pg_ivm RPM包可能并非总是最新版本。
当安装了pg_ivm
后,将创建以下对象。
使用create_immv
函数创建IMMV。
create_immv(immv_name text, view_definition text) RETURNS bigint
create_immv
定义一个新的查询IMMV。它会创建一个名为immv_name
的表,执行由view_definition
指定的查询,并用结果填充IMMV。该查询会被存储在pg_ivm_immv
中,以便之后进行增量视图维护时刷新。create_immv
返回创建的IMMV中的行数。
创建IMMV时,系统会自动创建一些触发器,以便在基表被修改时立即更新视图内容。此外,如果可能的话,还会自动为IMMV创建一个唯一索引。如果视图定义查询有GROUP BY子句,则会在GROUP BY表达式的列上创建唯一索引。如果视图有DISTINCT子句,则会在目标列表的所有列上创建唯一索引。否则,如果IMMV的目标列表中包含其基表的所有主键属性,则会在这些属性上创建唯一索引。在其他情况下,不会创建索引。
注意,如果你使用PostgreSQL 17或更高版本,在create_immv
运行期间,search_path
会临时更改 为pg_catalog, pg_temp
。
使用refresh_immv
函数刷新IMMV。
refresh_immv(immv_name text, with_data bool) RETURNS bigint
refresh_immv
完全替换IMMV的内容,就像REFRESH MATERIALIZED VIEW
命令对物化视图所做的那样。要执行此函数,你必须是IMMV的所有者(在PostgreSQL 16或更早版本中)或对IMMV拥有MAINTAIN
权限(在PostgreSQL 17或更高版本中)。旧内容将被丢弃。
with_data标志对应于REFRESH MATERIALIZED VIEW
命令的WITH [NO] DATA
选项。如果with_data为true,将执行后台查询以提供新数据,如果IMMV未填充,则创建用于维护视图的触发器。此外,如果可能且视图尚未拥有,还会为IMMV创建唯一索引。如果with_data为false,则不会生成新数据,IMMV将变为未填充状态,并且会从IMMV中删除触发器。注意,未填充的IMMV仍然可以扫描,尽管结果为空。这种行为在将来可能会改变,当扫描未填充的IMMV时可能会引发错误。
注意,如果你使用PostgreSQL 17或更高版本,在refresh_immv
运行期间,search_path
会临时更改为pg_catalog, pg_temp
。
get_immv_def
重构IMMV的底层SELECT命令。(这是一个反编译重构,而不是命令的原始文本。)
get_immv_def(immv regclass) RETURNS text
目录pg_ivm_immv
存储IMMV信息。
名称 | 类型 | 描述 |
---|---|---|
immvrelid | regclass | IMMV的OID |
viewdef | text |