关于物化视图完全刷新时的一点提醒。

[复制链接]
查看11 | 回复9 | 2012-7-12 18:47:29 | 显示全部楼层 |阅读模式
ORACLE10204。
曾人听说,10G的完全刷新在删除老数据时,和9I的些不一样,在10G里,删除前先DELETE 物化视图,而在9I,则是TRUNCATE,
刚才作了个10G的测试,如下:
1物化视图语句[/COLOR]
SCOTT@bi>select * from user_mviews;
OWNER
MVIEW_NAME
CONTAINER_NAME
QUERY

------------------------------ ------------------------------ ------------------------------ ---------------------------------------------
SCOTT
EMP_MV
EMP_MV
select * from emp5@tonc_scott

...
4 rows selected.
Elapsed: 00:00:00.03
2源表数据[/COLOR]
SCOTT@bi>select * from emp5@tonc_scott;
A
----------
8
2
2 rows selected.
Elapsed: 00:00:00.00
3物化视图数据[/COLOR]
SCOTT@bi>select * from EMP_MV;
A
----------
1
Elapsed: 00:00:00.01
4用10046跟踪刷新过程。[/COLOR]
SCOTT@bi>alter session set events '10046 trace name context forever, level 12';
Session altered.
Elapsed: 00:00:00.01
SCOTT@bi>exec dbms_mview.refresh('EMP_MV','C');
PL/SQL procedure successfully completed.
Elapsed: 00:00:01.92
SCOTT@bi>alter session set events '10046 trace name context off';
Session altered.
Elapsed: 00:00:00.00
SCOTT@bi>select * from EMP_MV;
A
----------
8
2
2 rows selected.
Elapsed: 00:00:00.00
SCOTT@bi>select sysdate from dual;
SYSDATE
-------------------
2009-08-12 09:46:54
Elapsed: 00:00:00.01
5物化视图版本[/COLOR]
SCOTT@bi>select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE10.2.0.4.0Production
TNS for 64-bit Windows: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production
5 rows selected.
Elapsed: 00:00:00.03

6解析10046跟踪文件,发现这两句,证实上面的一个说法。[/COLOR]
delete from "SCOTT"."EMP_MV"
INSERT /*+ BYPASS_RECURSIVE_CHECK */ INTO "SCOTT"."EMP_MV" select * from
emp5@tonc_scott
7只是我手头没有9I版本的库,没法测试9I的情况。[/COLOR]
不清楚ORACLE为什么会用DELETE 而非TRUNCATE,即便TRUNCATE没法处理外键,也不至于作此修改,毕竟大数据量时,两者效率明显不一样?
回复

使用道具 举报

千问 | 2012-7-12 18:47:29 | 显示全部楼层
由truncate换成delete没什么奇怪,如果truncate的话,刷新失败后,视图数据全部丢失。 而delete或许可以回滚。至少保证视图数据还在。
这个过程我也跟踪过,的确是通过delete from view。
回复

使用道具 举报

千问 | 2012-7-12 18:47:29 | 显示全部楼层
失败了可以再刷新获取,若老数据还可以使用,那何必刷新?
回复

使用道具 举报

千问 | 2012-7-12 18:47:29 | 显示全部楼层
按你这么说,如果数据truncate了,然后刷新又失败了。 那你告诉我怎么办? 连查询都不能。
我觉得这个仅仅是一个ORACLE的想法而已,或许保证首先刷新失败了还能查询。其实说白了truncate和delete都是删除数据,而且delete速度还更慢,那你说为什么要换?
回复

使用道具 举报

千问 | 2012-7-12 18:47:29 | 显示全部楼层
原帖由 tom_fans 于 2009-8-12 10:50 发表
按你这么说,如果数据truncate了,然后刷新又失败了。 那你告诉我怎么办? 连查询都不能。
我觉得这个仅仅是一个ORACLE的想法而已,或许保证首先刷新失败了还能查询。其实说白了truncate和delete都是删除数据,而且delete速度还更慢,那你说为什么要换?

失败了再刷新,你得考虑刷新失败是很少出现;你这说法,DELETE的刷新失败后,还可以查询了,是没有道理的,或许人家要的数据已经千变万化了,
老数据留给人家,没任何意义。再者,数据库量大的时候,删除都很困难,很可能就在这一步失败,毕竟INSERT比DELETE简单得多。
回复

使用道具 举报

千问 | 2012-7-12 18:47:29 | 显示全部楼层
刷新指定ATOMIC_REFRESH = false,则采用TRUNCATE + APPEND方式
默认为TRUE,则使用DELETE + INSERT方式
参考:http://yangtingkun.itpub.net/post/468/473736
回复

使用道具 举报

千问 | 2012-7-12 18:47:29 | 显示全部楼层
因为10g的新功能flash back,你truncate的后就不能flashback了。所以改成delete,也是oracle的必然。相辅相承。
回复

使用道具 举报

千问 | 2012-7-12 18:47:29 | 显示全部楼层
原帖由 ZALBB 于 2009-8-12 11:08 发表

失败了再刷新,你得考虑刷新失败是很少出现;你这说法,DELETE的刷新失败后,还可以查询了,是没有道理的,或许人家要的数据已经千变万化了,
老数据留给人家,没任何意义。再者,数据库量大的时候,删除都很困难,很可能就在这一步失败,毕竟INSERT比DELETE简单得多。

如果你的物化视图是用户直接查询的对象,你就不会持有这个观点了。
不管刷新是否失败,TRUNCATE操作一致性,事务性已经被破坏,在INSERT完成之前,所有访问物化视图的用户得到的都是0条记录。
回复

使用道具 举报

千问 | 2012-7-12 18:47:29 | 显示全部楼层
有些东西觉得不一定设计时oracle没考虑到我们想得,为什么还选了delete,就是为了推他的新技术。玩的就是概念。
回复

使用道具 举报

千问 | 2012-7-12 18:47:29 | 显示全部楼层
我也觉得这个仅仅是一个ORACLE的判断准则而已。 的确视图刷新失败了,数据前变万化,以前的数据甚至可能造成错误都有可能。 但是不管如何,ORACLE还是保证刷新失败还能查询而已,不管以前的数据是否会造成问题,这个要靠用户来判断。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行