PostgreSQL 9.4版本的物化视图更新

postgresql的9.4版本出来有一段时间了,也更新了很多内容,其中之一是比较感兴趣的物化视图的更新,对比原先的物化视图语法,新增了一个CONCURRENTLY参数。

一、新语法:

--创建语法,未有更新
CREATE MATERIALIZED VIEW table_name
    [ (column_name [, ...] ) ]
    [ WITH ( storage_parameter [= value] [, ... ] ) ]
    [ TABLESPACE tablespace_name ]
    AS query
    [ WITH [ NO ] DATA ]

--刷新语法
REFRESH MATERIALIZED VIEW [ CONCURRENTLY ] name
    [ WITH [ NO ] DATA ]

二、数据准备:

[[email protected] ~]$ psql
psql (9.4.1)
Type "help" for help.

postgres=# create table tbl_kenyon(id int,remark text);
CREATE TABLE
postgres=# insert into tbl_kenyon select generate_series(1,1000000),md5(random()::text);
INSERT 0 1000000
postgres=# select * from tbl_kenyon limit 10;
 id |              remark
----+----------------------------------
  1 | d4fc1c7440a4d1672028586c2bb76514
  2 | 5c1590519fa47f02db2895146a5f62a4
  3 | 1710ac4199746e9bfa188f1655d1f857
  4 | 6cae64191c2bc309a4884301e77b26ad
  5 | 813987a5c3af2d75bd0de6e288083b10
  6 | c52baa42cda22c89719bfb59dde1f78b
  7 | 491003337ea4e887c5ac24d174c691c6
  8 | 455cdf32b170fcf2b450c0b974fbf310
  9 | 43adb30aeb0a21ab35fdf97064ad1d21
 10 | 97dc1adc5484244a077e87ef36ecfe09
(10 rows)

--创建简单的物化视图
postgres=# create materialized view mv_tbl_kenyon as select * from tbl_kenyon ;
SELECT 1000000
postgres=# \d+
                              List of relations
 Schema |     Name      |       Type        |  Owner   | Size  | Description
--------+---------------+-------------------+----------+-------+-------------
 public | mv_tbl_kenyon | materialized view | postgres | 65 MB |
 public | tbl_kenyon    | table             | postgres | 65 MB |
(2 rows)

三、测试用例:

--测试不带concurrently
postgres=# insert into tbl_kenyon values(1000001,md5(random()::text));
INSERT 0 1
postgres=# select max(id) from mv_tbl_kenyon ;
   max
---------
 1000000
(1 row)

postgres=# \timing
Timing is on.
postgres=# refresh materialized view mv_tbl_kenyon ;
REFRESH MATERIALIZED VIEW
Time: 2056.460 ms

--测试带concurrently,需要建一个唯一索引
postgres=# insert into tbl_kenyon values(1000002,md5(random()::text));
INSERT 0 1
Time: 9.434 ms

postgres=# refresh materialized view concurrently mv_tbl_kenyon;
ERROR:  cannot refresh materialized view "public.mv_tbl_kenyon" concurrently
HINT:  Create a unique index with no WHERE clause on one or more columns of the materialized view.
Time: 22109.877 ms
postgres=# create unique index idx_ken on mv_tbl_kenyon(id);
CREATE INDEX
Time: 707.721 ms
postgres=# select max(id) from mv_tbl_kenyon ;
   max
---------
 1000001
(1 row)

Time: 1.110 ms
postgres=# begin;
BEGIN
postgres=# refresh materialized view concurrently mv_tbl_kenyon;
REFRESH MATERIALIZED VIEW
Time: 24674.739 ms

--如果在refresh的时候,前面加个begin;
--还能发现在开启的另外的session里面,是不会阻塞查询的,反之不加concurrently会阻塞
postgres=# select * from mv_tbl_kenyon limit 10;
 id |              remark
----+----------------------------------
  1 | d4fc1c7440a4d1672028586c2bb76514
  2 | 5c1590519fa47f02db2895146a5f62a4
  3 | 1710ac4199746e9bfa188f1655d1f857
  4 | 6cae64191c2bc309a4884301e77b26ad
  5 | 813987a5c3af2d75bd0de6e288083b10
  6 | c52baa42cda22c89719bfb59dde1f78b
  7 | 491003337ea4e887c5ac24d174c691c6
  8 | 455cdf32b170fcf2b450c0b974fbf310
  9 | 43adb30aeb0a21ab35fdf97064ad1d21
 10 | 97dc1adc5484244a077e87ef36ecfe09
(10 rows)

四、源码

相关唯一索引的源码,在matview.c里面可以查看:

--先初始化唯一索引是false
foundUniqueIndex = false;

--如果找到唯一索引赋值为true
if (foundUniqueIndex)
     appendStringInfoString(&querybuf, " AND ");

     colname = quote_identifier(NameStr((tupdesc->attrs[attnum - 1])->attname));
     appendStringInfo(&querybuf, "newdata.%s ", colname);
     type = attnumTypeId(matviewRel, attnum);
     op = lookup_type_cache(type, TYPECACHE_EQ_OPR)->eq_opr;
     mv_GenerateOper(&querybuf, op);
     appendStringInfo(&querybuf, " mv.%s", colname);

      foundUniqueIndex = true;

--如果找不到唯一索引报error
if (!foundUniqueIndex)
                ereport(ERROR,(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
                errmsg("cannot refresh materialized view \"%s\" concurrently",matviewname),
                errhint("Create a unique index with no WHERE clause on one or more columns of the materialized view.")));
        appendStringInfoString(&querybuf, " AND newdata OPERATOR(pg_catalog.*=) mv) "
                                "WHERE newdata IS NULL OR mv IS NULL " "ORDER BY tid");

五、总结:

1.新版的物化视图新增了concurrently参数,可以使在刷新视图时不会锁住该物化视图的查询工作

2.该参数的原理和优缺点与索引的concurrently类似,以时间来换取查询锁,刷新的速度会变得很慢

3.增量刷新的参数还没有,比较遗憾

六、参考:

1.http://www.postgresql.org/docs/9.4/static/sql-creatematerializedview.html
2.http://francs3.blog.163.com/blog/static/405767272014421104127225/

3.src/backend/commands/matview.c

时间: 2024-10-15 07:22:33

PostgreSQL 9.4版本的物化视图更新的相关文章

PostgreSQL定时刷新物化视图的一种简单方法

PostgreSQL 9.3开始支持物化视图,9.4又增加了非阻塞的CONCURRENTLY选项,但REFRESH时却不支持类似START WITH ... NEXT ...的定时刷新选项. 如何实现定时刷新物化视图?百度的结果主要是以下三种: 借助操作系统,如Linux/Unix的crontab或Windows的定时任务: 借助插件pgAgent: 使用触发器,一般为语句级(... FOR EACH STATEMENT ...). 近日接触到\watch命令,发现了一种新的刷新物化视图的方法.

【PostgreSQL】物化视图

PostgreSQL 9.3 以后出现了物化视图.物化视图是由实实在在的数据组成,这是和一般视图的根本区别. 1. 物化视图创建语法如下: --创建语法 CREATE MATERIALIZED VIEW table_name [ (column_name [, ...] ) ] [ WITH ( storage_parameter [= value] [, ... ] ) ] [ TABLESPACE tablespace_name ] AS query [ WITH [ NO ] DATA ]

oracle物化视图快速更新

建立测试表 create table T_table nologging as select * from dba_objects; create table t_table_1 nologging as select * from dba_tables; --建立日志记录 create materialized view log on T_table with rowid ,sequence(object_name,object_type,owner) including new values

postgresql9.5 物化视图测试

视图是指数据库只存储定义该视图的查询语句(内容是查询时产生),而物化视图是一个其查询语句查询后的内容并存储的视图(内容是创建物化视图刷新视图时产生,数据可修改.独立).因为物化视图是视图的一个物化表结构,但是里面的数据是创建时刷新查询到额数据,当原数据更新修改时如果物化视图的表没有更新会造成数据的不一致.从9.4开始增加增量刷新,9.5的版本中支持物化视图也支持索引,修改表空间,指定用户访问权限 postgresql9.5物化视图测试: search package: sudo apt-cach

物化视图的刷新(转载)

转载源自于:http://czmmiao.iteye.com/blog/1827254 物化视图 物化视图是包括一个查询结果的数据库对像,它是远程数据的的本地副本,或者用来生成基于数据表求和的汇总表.物化视图存储基于远程表的数据,也可以称为快照.物化视图可以基于表查询,视图和其它的物化视图.通常情况下,在复制环境下,物化视图被称为主表,在数据仓库中称为明细表.对于复制,物化视图允许你在本地维护远程数据的副本,这些副本是只读的.如果你想修改本地副本,必须用高级复制的功能.当你想从一个表或视图中抽取

转:oracle物化视图学习笔记

最近学习了一下物化视图,正好经理不在,把学习结果贴出来供大家一起研究一下吧. 先看一下物化视图的大概含义吧,感觉baidu的定义还不错 Baidu代码   物化视图,它是用于预先计算并保存表连接或聚集等耗时较多的操作的结果,这样,在执行查询时,就可以避免进行这些耗时的操作,从而快速的得到结果.物化视图有很多方面和索引很相似:使用物化视图的目的是为了提高查询性能:物化视图对应用透明,增加和删除物化视图不会影响应用程序中SQL 语句的正确性和有效性:物化视图需要占用存储空间:当基表发生变化时,物化视

ORACLE物化视图详解

一.物化的一般用法物化视图是一种特殊的物理表,"物化"(Materialized)视图是相对普通视图而言的.普通视图是虚拟表,应用的局限性大,任何对视图的查询,oracle都实际上转换为视图SQL语句的查询.这样对整体查询性能的提高,并没有实质上的好处. 1.物化视图的类型ON DEMAND.ON COMMIT.二者的区别在于刷新方法的不同,ON DEMAND顾名思义,仅在该物化视图"需要"被刷新了,才进行刷新(REFRESH),即更新物化视图,以保证和基表数据的一

oracle 静态视图 物化视图

搜了几分钟才找到一篇靠谱的文章,原来搜 静态视图 出来一堆,现在谷歌也变傻了?都改名 物化 呵呵旧文章估计都因无人访问 系统升级沉入海底了.快清明了 给这些 夭亡的技术文章烧点纸钱! 原文链接:http://www.bitscn.com/pdb/oracle/200904/160511_5.html 物化视图是一种特殊的物理表,"物化"(Materialized)视图是相对普通视图而言的.普通视图是虚拟表,应用的局限性大,任何对视图的查询,Oracle都实际上转换为视图SQL语句的查询

Oracle 10g通过创建物化视图实现不同数据库间表级别的数据同步

摘自:http://blog.csdn.net/javaee_sunny/article/details/53439980 目录(?)[-] Oracle 10g 物化视图语法如下 实例演示 主要步骤 在A节点创建原表和物化视图日志 在B节点创建连接A节点的远程链接 在B节点处创建目标表和与目标表名称相同的物化视图 在B节点处刷新物化视图 升级采用存储过程定时任务JOB方式定时刷新物化视图 进一步优化 文章更新记录 参考文章 Oracle 10g 物化视图语法如下: create materia