一步步实现物化视图FAST刷新

一步步实现物化视图FAST刷新

fast刷新指的物化视图的增量刷新。

创建物化视图

需要使用SQL语句

SQL> select e.empno,e.ename,e.deptno

from emp e,dept d

where e.deptno=d.deptno

and d.loc='DALLAS';

 

     EMPNO ENAME          DEPTNO

---------- ---------- ----------

      7566 JONES              20

      7902 FORD               20

      7876 ADAMS              20

      7369 SMITH              20

      7788 SCOTT              20

创建materialized view

SQL> create materialized view emp_loc_mv

  2  as

  3  select e.empno,e.ename,e.deptno

  4  from emp e,dept d

  5  where e.deptno=d.deptno

  6  and d.loc='DALLAS';

 

Materialized view created.

查看物化视图结果

SQL> select * from emp_loc_mv;

 

     EMPNO ENAME          DEPTNO

---------- ---------- ----------

      7566 JONES              20

      7902 FORD               20

      7876 ADAMS              20

      7369 SMITH              20

      7788 SCOTT              20

查看该物化视图详细信息:

1.获得DDL定义

SQL> set long 20000000

SQL> set pagesize 0

SQL> select dbms_metadata.get_ddl('MATERIALIZED VIEW','EMP_LOC_MV','SCOTT') from dual;

ERROR:

ORA-31600: invalid input value MATERIALIZED VIEW for parameter OBJECT_TYPE in

function GET_DDL

ORA-06512: at "SYS.DBMS_METADATA", line 5088

ORA-06512: at "SYS.DBMS_METADATA", line 7589

ORA-06512: at line 1

get_ddl的时候提示没有“MATERIALIZED VIEW”这个类型,下面改为table

SQL> select dbms_metadata.get_ddl('TABLE','EMP_LOC_MV','SCOTT') from dual;

 

CREATE TABLE "SCOTT"."EMP_LOC_MV"

   (    "EMPNO" NUMBER(4,0),

        "ENAME" VARCHAR2(10),

        "DEPTNO" NUMBER(2,0)

   ) SEGMENT CREATION IMMEDIATE

PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255

NOCOMPRESS LOGGING

STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1

BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

TABLESPACE "USERS"

在该DDL信息中,并没有记录物化视图相关的刷新信息。

DDL的相关内容还可以通过user_mviews数据字典获得select mview_name ,query from user_mviews;

 

相关刷新信息可以通过dbms_mview.explain_mview查看:

SQL> @?/rdbms/admin/utlxmv.sql;

SQL> exec dbms_mview.explain_mview('EMP_LOC_MV');

SQL> SELECT capability_name,  possible, SUBSTR(related_text,1,8)

 AS rel_text, SUBSTR(msgtxt,1,60) AS msgtxt

  FROM MV_CAPABILITIES_TABLE

  ORDER BY seq;

PCT                            N

REFRESH_COMPLETE               Y

REFRESH_FAST                  N

REWRITE                        N

PCT_TABLE                      N EMP      relation is not a partitioned table

PCT_TABLE                      N DEPT     relation is not a partitioned table

REFRESH_FAST_AFTER_INSERT      N D        the SELECT list does not have the rowids of all the detail t

REFRESH_FAST_AFTER_INSERT      N SCOTT.EM the detail table does not have a materialized view log

REFRESH_FAST_AFTER_INSERT      N SCOTT.DE the detail table does not have a materialized view log

REFRESH_FAST_AFTER_ONETAB_DML  N          see the reason why REFRESH_FAST_AFTER_INSERT is disabled

REFRESH_FAST_AFTER_ANY_DML     N          see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled

REFRESH_FAST_PCT               N          PCT is not possible on any of the detail tables in the mater

REWRITE_FULL_TEXT_MATCH        N          query rewrite is disabled on the materialized view

REWRITE_PARTIAL_TEXT_MATCH     N          query rewrite is disabled on the materialized view

REWRITE_GENERAL                N          query rewrite is disabled on the materialized view

REWRITE_PCT                    N          general rewrite is not possible or PCT is not possible on an

PCT_TABLE_REWRITE              N EMP      relation is not a partitioned table

PCT_TABLE_REWRITE              N DEPT     relation is not a partitioned table

 

从上面可以看出,该物化视图是不支持REFRESH_FAST

测试物化视图的refresh  fast

修改基表

SQL> insert into emp values(3333,'tan','qingru',2222,sysdate,1111,300,20);

SQL> commit;

 

再次分别查询物化视图和物化视图定义的SQL

SQL> select * from emp_loc_mv;

      7566 JONES              20

      7902 FORD               20

      7876 ADAMS              20

      7369 SMITH              20

      7788 SCOTT              20

 

SQL> select e.empno,e.ename,e.deptno

  2  from emp e,dept d

  3  where e.deptno=d.deptno

  4  and d.loc='DALLAS';

      7566 JONES              20

      7369 SMITH              20

      7788 SCOTT              20

      7902 FORD               20

      7876 ADAMS              20

      3333 tan                20

SQL> select * from emp_loc_mv;

      7566 JONES              20

      7902 FORD               20

      7876 ADAMS              20

      7369 SMITH              20

      7788 SCOTT              20

 

物化视图前后都没有刷新:

 

做一次手工刷新:

SQL> exec dbms_mview.refresh('EMP_LOC_MV');

查看结果。

SQL> select * from emp_loc_mv;

      7566 JONES              20

      7369 SMITH              20

      7788 SCOTT              20

      7902 FORD               20

      7876 ADAMS              20

      3333 tan                20

6 rows selected.

将该物化视图改为FAST刷新:

直接更改

SQL> alter materialized view emp_loc_mv refresh fast;

alter materialized view emp_loc_mv refresh fast

                                              *

ERROR at line 1:

ORA-12015: cannot create a fast refresh materialized view from a complex query

无法创建,回头再读上面dbms_mview.explain_mview的结果。

REFRESH_FAST_AFTER_INSERT      N D        the SELECT list does not have the rowids of all the detail t

REFRESH_FAST_AFTER_INSERT      N SCOTT.EM the detail table does not have a materialized view log

REFRESH_FAST_AFTER_INSERT      N SCOTT.DE the detail table does not have a materialized view log

上面的提示主要说select中没有表的rowid,另外两个表没有materialized view log

 

解决问题1select包含rowid

改变物化视图结构参考官方的alter materialized view:

http://docs.oracle.com/cd/E11882_01/server.112/e26088/statements_2002.htm#SQLRF00808

通过alter materialized view可以做:

·         To change its storage characteristics

·         To change its refresh method, mode, or time

·         To alter its structure so that it is a different type of materialized view

·         To enable or disable query rewrite

没有找到直接修改办法,所以决定删除再建(好像视图和物化视图都是这个方法):

SQL> drop materialized view emp_loc_mv;

SQL> create materialized view emp_loc_mv

  as

  select e.rowid rowide,d.rowid rowidd,e.empno,e.ename,e.deptno

  from emp e,dept d

  where e.deptno=d.deptno

  and d.loc='DALLAS';

再次做explain_mview

SQL> truncate table MV_CAPABILITIES_TABLE;

---旧的信息依旧在,删除旧的信息比修改select方便

SQL> exec dbms_mview.explain_mview('EMP_LOC_MV');

SQL> SELECT capability_name,  possible, SUBSTR(related_text,1,8)

 AS rel_text, SUBSTR(msgtxt,1,60) AS msgtxt

FROM MV_CAPABILITIES_TABLE

ORDER BY seq;

PCT                            N

REFRESH_COMPLETE               Y

REFRESH_FAST                   N

REWRITE                        N

PCT_TABLE                      N EMP      relation is not a partitioned table

PCT_TABLE                      N DEPT     relation is not a partitioned table

REFRESH_FAST_AFTER_INSERT      N SCOTT.EM the detail table does not have a materialized view log

REFRESH_FAST_AFTER_INSERT      N SCOTT.DE the detail table does not have a materialized view log

REFRESH_FAST_AFTER_ONETAB_DML  N          see the reason why REFRESH_FAST_AFTER_INSERT is disabled

REFRESH_FAST_AFTER_ANY_DML     N          see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled

REFRESH_FAST_PCT               N          PCT is not possible on any of the detail tables in the mater

REWRITE_FULL_TEXT_MATCH        N          query rewrite is disabled on the materialized view

REWRITE_PARTIAL_TEXT_MATCH     N          query rewrite is disabled on the materialized view

REWRITE_GENERAL                N          query rewrite is disabled on the materialized view

REWRITE_PCT                    N          general rewrite is not possible or PCT is not possible on an

PCT_TABLE_REWRITE              N EMP      relation is not a partitioned table

PCT_TABLE_REWRITE              N DEPT     relation is not a partitioned table

解决问题2:创建materialized view log

创建一个物化视图日志。做到自动刷新。

 

SQL> create materialized view log on emp

 with rowid,sequence

  (EMPNO)

  4  including new values;

在这只做了一个表上的一例。再次做检查

REFRESH_FAST_AFTER_INSERT     N SCOTT.DE the detail table does not have a materialized view log

提示dept表上没有materialized view log

dept表上再做materialized view log

SQL> create materialized view log on dept

  2  with rowid,sequence

  3  (LOC)

  4  including new values;

又有下面1条提示:

REFRESH_FAST_AFTER_INSERT      N SCOTT.DE mv log is newer than last full refresh

对视图做一次手工刷新

exec dbms_mview.refresh('EMP_LOC_MV');

刷新后,再次检查的结果。

REFRESH_COMPLETE               Y

REFRESH_FAST                   Y

REWRITE                        N

PCT_TABLE                      N EMP      relation is not a partitioned table

PCT_TABLE                      N DEPT     relation is not a partitioned table

REFRESH_FAST_AFTER_INSERT      Y

REFRESH_FAST_AFTER_ONETAB_DML  Y

REFRESH_FAST_AFTER_ANY_DML     Y

REFRESH_FAST_PCT               N          PCT is not possible on any of the detail tables in the mater

REWRITE_FULL_TEXT_MATCH        N          query rewrite is disabled on the materialized view

REWRITE_PARTIAL_TEXT_MATCH     N          query rewrite is disabled on the materialized view

REWRITE_GENERAL                N          query rewrite is disabled on the materialized view

REWRITE_PCT                    N          general rewrite is not possible or PCT is not possible on an

PCT_TABLE_REWRITE              N EMP      relation is not a partitioned table

PCT_TABLE_REWRITE              N DEPT     relation is not a partitioned table

再次测试fast刷新

SQL> insert into emp values(111,'tan','qingru',2222,sysdate,1111,300,20);

SQL> commit;

 

SQL> select * from emp_loc_mv;

……

6 rows selected.

依然没有做FAST刷新:

手工改动物化视图为FAST刷新再试

SQL> alter materialized view emp_loc_mv refresh fast;

SQL> insert into emp values(222,'tan','qingru',2222,sysdate,1111,300,20);

SQL> commit;

SQL> select * from emp_loc_mv;

6 rows selected.

select e.rowid rowide,d.rowid rowidd,e.empno,e.ename,e.deptno

  from emp e,dept d

  where e.deptno=d.deptno

and d.loc='DALLAS';

8 rows selected.

SQL> select * from emp_loc_mv;

6 rows selected.

经测试又没有能fast刷新

 

SQL> select * from MLOG$_EMP;

       222 AAASZHAAEAAAACXAAR                                                                                              10003 01-JAN-00 I N FEFF                                                                                                        2.2519E+15

       111 AAASZHAAEAAAACXAAQ                                                                                              10002 18-APR-13 I N FEFF                                                                                                        2.2519E+15

 

SQL> select * from MLOG$_DEPT ;

 

no rows selected

增加emp中该物化视图相关的列

SQL> alter materialized view log on emp add(ENAME);

SQL> alter materialized view log on emp add(DEPTNO);

再次测试,依然未刷新

解决问题3:修改为on commit

查看了相关文档

       ON DEMAND: Manual refresh using procedures in DBMS_MVIEW package (default)

原来理解on demand是需要的时候刷新,在这解释为用dbms_mview手动刷新,不指定默认为on demand,所以需要修改为on commit:

       ON COMMIT: Refresh performed at transaction commit

      Only possible for fast-refreshablematerialized views

      ON COMMIT REFRESH object privilege needed

      In case of failure, subsequent refreshes are manual

 

SQL> alter materialized view emp_loc_mv refresh on commit;

alter materialized view emp_loc_mv refresh on commit

                                                   *

ERROR at line 1:

ORA-32337: cannot alter materialized view with pending changes refresh on commit

对这个错误,相关的解释:

ORA-32337: cannot alter materialized view with pending changes refresh on commit Cause: There are some pending changes in the detail tables

Action: Execute an on-demand refresh on the materialized view to synchronize the data between the materialized view and the detail tables and then issue an ALTER MATERIALIZED VIEW statement.

需要一次手动刷新:

SQL> exec dbms_mview.refresh('EMP_LOC_MV');

SQL> alter materialized view emp_loc_mv refresh on commit;

Materialized view altered.

再次测试

SQL> insert into emp values(555,'tan','qingru',2222,sysdate,1111,300,20);

SQL> commit;

SQL> select * from emp_loc_mv;

10 rows selected.

 

SQL> select e.rowid rowide,d.rowid rowidd,e.empno,e.ename,e.deptno

  2    from emp e,dept d

  3    where e.deptno=d.deptno

  4  and d.loc='DALLAS';

10 rows selected.

 

经测试fast刷新正常。

你可能感兴趣的:(一步步实现物化视图FAST刷新)