一步步实现物化视图FAST刷新
fast刷新指的物化视图的增量刷新。
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
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
修改基表
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.
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。
改变物化视图结构参考官方的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
创建一个物化视图日志。做到自动刷新。
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
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刷新:
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);
再次测试,依然未刷新
查看了相关文档
• 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刷新正常。