物化视图的修改语句ALTER MATERIALIZED VIEW包含了CONSIDER FRESH语句。通过这个语句可以使得数据库认为物化视图已经是刷新后的状态。同时可以使得这个物化视图对于查询重新生效。
这篇简单讨论CONSIDER FRESH语句的用法。
通过一个简单的例子说明如何使用CONSIDER FRESH语句:
SQL> CREATE TABLE T
2 (ID NUMBER PRIMARY KEY,
3 NAME VARCHAR2(30));
表已创建。
SQL> CREATE MATERIALIZED VIEW LOG ON T;
实体化视图日志已创建。
SQL> CREATE MATERIALIZED VIEW MV_T1
2 REFRESH FAST
3 AS SELECT *
4 FROM T;
实体化视图已创建。
SQL> INSERT INTO T
2 SELECT ROWNUM, TNAME
3 FROM TAB;
已创建8行。
SQL> EXEC DBMS_MVIEW.REFRESH('MV_T1')
PL/SQL 过程已成功完成。
SQL> SELECT COUNT(*)
2 FROM MV_T1;
COUNT(*)
----------
8
SQL> INSERT INTO T
2 VALUES (9, 'TEST');
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> SELECT COUNT(*)
2 FROM T;
COUNT(*)
----------
9
SQL> ALTER MATERIALIZED VIEW MV_T1
2 CONSIDER FRESH;
实体化视图已更改。
SQL> SELECT COUNT(*)
2 FROM MV_T1;
COUNT(*)
----------
8
SQL> INSERT INTO T
2 VALUES (10, 'NEW');
已创建 1 行。
SQL> EXEC DBMS_MVIEW.REFRESH('MV_T1')
PL/SQL 过程已成功完成。
SQL> SELECT *
2 FROM MV_T1;
ID NAME
---------- ------------------------------
1 MLOG$_T
2 MV_T1
3 RUPD$_T
4 T
5 T_PART_HASH
6 T_PART_INTER
7 T_PART_LIST
8 T_PART_RANGE
10 NEW
已选择9行。
SQL> INSERT INTO MV_T1
2 VALUES (9, 'TEST');
INSERT INTO MV_T1
*
第 1 行出现错误:
ORA-01732: 此视图的数据操纵操作非法
可以看到,正常的物化视图可以利用CONSIDER FRESH,之后也不影响物化视图的快速刷新,但是物化视图和原表的数据可能会查询差异。
而这种差异在物化视图端是没有办法通过DML修改来修正的。
尝试建立可写的物化视图:
SQL> CREATE MATERIALIZED VIEW MV_T2
2 REFRESH FAST
3 FOR UPDATE
4 AS SELECT *
5 FROM T;
实体化视图已创建。
SQL> INSERT INTO T
2 VALUES (11, 'ABC');
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> INSERT INTO MV_T2
2 VALUES (11, 'AB');
已创建 1 行。
SQL> ALTER MATERIALIZED VIEW MV_T2
2 CONSIDER FRESH;
ALTER MATERIALIZED VIEW MV_T2
*
第 1 行出现错误:
ORA-03001: 未实施的功能
可写的物化视图可以执行DML,但是不能执行CONSIDER FRESH语句,那么使用CONSIDER FRESH只能通知Oracle物化视图已经处于FRESH状态,而不能进行任何的实际修改吗,事实上,CONSIDER FRESH支持分区装载操作。
SQL> CREATE TABLE T_PART
2 (ID NUMBER,
3 NAME VARCHAR2(30),
4 CREATE_DATE DATE)
5 PARTITION BY RANGE (CREATE_DATE)
6 (PARTITION P1 VALUES LESS THAN (TO_DATE('2009-1', 'YYYY-MM')),
7 PARTITION P2 VALUES LESS THAN (TO_DATE('2010-1', 'YYYY-MM')),
8 PARTITION P3 VALUES LESS THAN (TO_DATE('2011-1', 'YYYY-MM')));
表已创建。
SQL> ALTER TABLE T_PART
2 ADD CONSTRAINT PK_T_PART
3 PRIMARY KEY (ID);
表已更改。
SQL> INSERT INTO T_PART
2 SELECT ROWNUM, OBJECT_NAME, CREATED
3 FROM ALL_OBJECTS
4 WHERE CREATED < TO_DATE('2010-1', 'YYYY-MM');
已创建55629行。
SQL> COMMIT;
提交完成。
SQL> CREATE MATERIALIZED VIEW LOG ON T_PART;
实体化视图日志已创建。
SQL> CREATE MATERIALIZED VIEW MV_T_PART
2 PARTITION BY RANGE (CREATE_DATE)
3 (PARTITION P1 VALUES LESS THAN (TO_DATE('2009-1', 'YYYY-MM')),
4 PARTITION P2 VALUES LESS THAN (TO_DATE('2010-1', 'YYYY-MM')),
5 PARTITION P3 VALUES LESS THAN (TO_DATE('2011-1', 'YYYY-MM')))
6 REFRESH FAST
7 AS SELECT *
8 FROM T_PART;
实体化视图已创建。
SQL> CREATE TABLE T_LOAD
2 (ID NUMBER PRIMARY KEY,
3 NAME VARCHAR2(30),
4 CREATE_DATE DATE);
表已创建。
SQL> INSERT INTO T_LOAD
2 SELECT 55629 + ROWNUM, OBJECT_NAME, CREATED
3 FROM ALL_OBJECTS
4 WHERE CREATED >= TO_DATE('2010-1', 'YYYY-MM');
已创建61行。
SQL> COMMIT;
提交完成。
SQL> ALTER TABLE T_PART
2 EXCHANGE PARTITION P3
3 WITH TABLE T_LOAD;
表已更改。
SQL> INSERT INTO T_LOAD
2 SELECT 55629 + ROWNUM, OBJECT_NAME, CREATED
3 FROM ALL_OBJECTS
4 WHERE CREATED >= TO_DATE('2010-1', 'YYYY-MM');
INSERT INTO T_LOAD
*
第 1 行出现错误:
ORA-01502: 索引 'TEST.SYS_C0011198' 或这类索引的分区处于不可用状态
SQL> ALTER INDEX SYS_C0011198 REBUILD;
索引已更改。
SQL> INSERT INTO T_LOAD
2 SELECT 55629 + ROWNUM, OBJECT_NAME, CREATED
3 FROM ALL_OBJECTS
4 WHERE CREATED >= TO_DATE('2010-1', 'YYYY-MM');
已创建61行。
SQL> COMMIT;
提交完成。
SQL> ALTER TABLE MV_T_PART
2 EXCHANGE PARTITION P3
3 WITH TABLE T_LOAD;
表已更改。
SQL> ALTER MATERIALIZED VIEW MV_T_PART
2 CONSIDER FRESH;
实体化视图已更改。
SQL> SELECT COUNT(*)
2 FROM T_PART;
COUNT(*)
----------
55690
SQL> SELECT COUNT(*)
2 FROM MV_T_PART;
COUNT(*)
----------
55690
这是一个简单的利用CONSIDER FRESH语句的例子,通过EXCHANGE分区的方式,是的物化视图和基表保持一致。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4227/viewspace-665837/ ,如需转载,请注明出处,否则将追究法律责任。