li
  当前位置:主页 > 性能优化 > 文章内容
li
物化视图的创建写法与刷新问题
来源: http://yangtingkun.itpub.net/  作者: yangtingkun    时间:2008-01-26   阅读:38  
本文章共2962字,分2页,当前第1页,快速翻页:
 

前些天和space6212讨论了一下这个问题,这里简单记录一下。


首先看看下面两个物化视图有什么区别:

SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30));

表已创建。

SQL> CREATE MATERIALIZED VIEW LOG ON T;

实体化视图日志已创建。

SQL> CREATE MATERIALIZED VIEW MV_T1 REFRESH FAST AS SELECT * FROM T;

实体化视图已创建。

SQL> CREATE MATERIALIZED VIEW MV_T2 REFRESH FAST AS SELECT T.* FROM T;

实体化视图已创建。

唯一的区别在于MV_T2在SELECT *的时候指明了T.*,不要小看这点区别,就是T.*和*的区别,就会导致两个物化视图在刷新时的表现截然不同。

为了展示问题,需要对基表添加一列,这对于普通的物化视图来说不是问题。物化视图日志会自动支持新增的列。

SQL> INSERT INTO T VALUES (1, 'YTK');

已创建 1 行。

SQL> ALTER TABLE T ADD AGE NUMBER(3);

表已更改。

SQL> EXEC DBMS_MVIEW.REFRESH('MV_T1')

PL/SQL 过程已成功完成。

SQL> EXEC DBMS_MVIEW.REFRESH('MV_T2')

PL/SQL 过程已成功完成。

快速刷新两个物化视图都没有产生问题,那么看看完全刷新的情况:

SQL> EXEC DBMS_MVIEW.REFRESH('MV_T1', 'C')

PL/SQL 过程已成功完成。

SQL> EXEC DBMS_MVIEW.REFRESH('MV_T2', 'C')
BEGIN DBMS_MVIEW.REFRESH('MV_T2', 'C'); END;

*
ERROR 位于第 1 行:
ORA-12018: 在创建"YANGTK"."MV_T2" 的代码时出现以下错误
ORA-00904: "AGE": 无效的标识符
ORA-06512: 在"SYS.DBMS_SNAPSHOT", line 794
ORA-06512: 在"SYS.DBMS_SNAPSHOT", line 851
ORA-06512: 在"SYS.DBMS_SNAPSHOT", line 832
ORA-06512: 在line 1

差异终于体现了。MV_T1的完全刷新没有任何问题,而对于MV_T2,完全刷新导致了错误的产生。

这个测试说明了两个问题。首先,两个物化视图是有区别的,否则不会一个在完全刷新时报错,而另一个在完全刷新时不报错。其次,物化视图的快速刷新和完全刷新的方法并不一样,否则不会快速刷新正常而完全刷新报错。

www.ixdba.net


先看第一个问题:

SQL> COL QUERY FORMAT A80
SQL> SELECT MVIEW_NAME, QUERY FROM USER_MVIEWS WHERE MVIEW_NAME LIKE 'MV_T_';

MVIEW_NAME QUERY
------------------------------ ------------------------------------------------
MV_T1 SELECT "T"."ID" "ID","T"."NAME" "NAME" FROM "T" "T"
MV_T2 SELECT T.* FROM T

由于MV_T2在*前面添加了T,物化视图的定义并不像MV_T1那样被全部解析为列的列表方式。在完全刷新的时候,MV_T2根据T重新展开,而此时由于增加了新的列,导致物化视图同步时查询列和插入列不匹配。

MV_T1则没有这个问题,MV_T1已经在创建物化视图的时候将列定义展开,因此新增的字段对MV_T1没有任何影响。

最后看看快速刷新和完全刷新的区别,在*前面添加了T之后,物化视图的定义并没有被展开。而物化视图快速刷新要顺利完成,就要求数据字典中必须有专门的地方来保留快速刷新需要使用的SQL语句:

SQL> ALTER SESSION SET SQL_TRACE = TRUE;

会话已更改。

SQL> EXEC DBMS_MVIEW.REFRESH('MV_T1')

PL/SQL 过程已成功完成。

SQL> ALTER SESSION SET SQL_TRACE = FALSE;

会话已更改。

TRACE文件内容比较长,下面仅摘录关键部分:

PARSING IN CURSOR #10 len=249 dep=1 uid=0 oct=3 lid=0 tim=18446744072015785716 hv=2055365415 ad='7db80b40'
SELECT operation#, cols, sql_txt, tabnum, fcmaskvec, ejmaskvec, setnum FROM sys.snap_refop$ WHERE ((operation# >= 0 AND operation# <= 6) OR operation# = 10) AND sowner = :1 AND vname = :2 AND instsite = :3 ORDER BY tabnum, setnum, operation#



阅读更多内容1 · 2 · 下一页>>


  上一篇: 小议物化视图与基表数据不一致的...   下一篇: 10203设置CURSOR_SHARING为SIMIL...
li
 §相关评论  
 热点文章

·Resize datafile导致ASM Crash
·在Oracle10g RAC下新增ASM磁盘
·ORACLE SQL性能优化系列 (一)
·oracle性能调优:管理oracle日志
·oracle RAC环境中系统时钟的调
·why:Rac的心跳线不支持交叉线?
·RAC的VIP及实例依赖关系:版本O
·如何启动DataGuard的备用数据库
·系统表空间IO错误 数据损坏处理
·不幸中的万幸:遭遇ORA-00600 [
·用ORACLE的高级复制实现内外网
li
 编辑推荐
·Resize datafile导致ASM Crash
·在Oracle10g RAC下新增ASM磁盘
·ORACLE SQL性能优化系列 (一)
·oracle性能调优:管理oracle日志
·oracle RAC环境中系统时钟的调
·why:Rac的心跳线不支持交叉线?
·RAC的VIP及实例依赖关系:版本O
·如何启动DataGuard的备用数据库
·系统表空间IO错误 数据损坏处理
·不幸中的万幸:遭遇ORA-00600 [
·用ORACLE的高级复制实现内外网
li
 相关篇章
·小议物化视图与基表数据不一致的...
·建立物化视图导致数据库实例崩溃
·ORA-600(999)错误(三)
·物化视图刷新过程中出现的约束冲...
·ORA-600(999)错误(二)
·GLOBAL_NAME相同的数据库中物化视...
·GLOBAL_NAME相同的数据库中物化视...
·物化视图复制快速刷新的限制(二...
·物化视图是否根据字段进行刷新(...
·物化视图是否根据字段进行刷新(...
·10203设置CURSOR_SHARING为SIMIL...
·小议物化视图与基表数据不一致的...
·包含复制环境的数据库迁移(二)
·包含复制环境的数据库迁移(一)
·inode耗尽导致No space left on ...
·在Oracle10g RAC下新增ASM磁盘组
·oracle RAC环境中系统时钟的调整
·why:Rac的心跳线不支持交叉线?
·RAC的VIP及实例依赖关系:版本Ora...
·如何启动DataGuard的备用数据库
 
li
设为首页 | 关于我们 | 技术服务 | 收藏本站 | 网站地图 | 联系方式 | 本站友情连接