yangtingkun
===========================================================
物化视图删除的顺序
===========================================================

以前写过一篇文章,介绍删除基于数据库链的物化视图时,要确保数据库链的存在,否则会导致物化视图注册信息无法清除。详细信息可以参考http://yangtingkun.itpub.net/post/468/88208

这里讨论的删除物化视图和删除物化视图日志的顺序。


首先强调一下,删除物化视图并不意味着要删除物化视图日志。因为物化视图日志可以同时支持多个物化视图的刷新,如果物化视图日志被删除,那么所有基于这个物化视图日志的物化视图无法再进行快速刷新。

这里讨论的情况是,仅有一个快速刷新的物化视图的情况,或者所有快速刷新的物化视图都准备重新建立的情况。

在这种前提下,先删除物化视图日志然后再删除物化视图。

还是通过一个例子来说明这种情况:

SQL> CREATE TABLE T AS SELECT ROWNUM ID, A.* FROM DBA_OBJECTS A WHERE 1 = 2;

表已创建。

SQL> CREATE TABLE T1 AS SELECT ROWNUM ID, A.* FROM DBA_OBJECTS A WHERE 1 = 2;

表已创建。

SQL> ALTER TABLE T ADD PRIMARY KEY (ID);

表已更改。

SQL> ALTER TABLE T1 ADD PRIMARY KEY (ID);

表已更改。

SQL> CREATE MATERIALIZED VIEW LOG ON T;

实体化视图日志已创建。

SQL> CREATE MATERIALIZED VIEW LOG ON T1;

实体化视图日志已创建。

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

实体化视图已创建。

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

实体化视图已创建。

SQL> INSERT INTO T VALEUS SELECT ROWNUM, A.* FROM DBA_OBJECTS A;

已创建50677行。

SQL> INSERT INTO T1 VALEUS SELECT ROWNUM, A.* FROM DBA_OBJECTS A;

已创建50677行。

SQL> COMMIT;

提交完成。

上面建立了两张完全一样的表,也建立了两个完全一样的物化视图,下面删除物化视图和物化视图日志,区别是一个先删除物化视图而另一个是先产生物化视图日志:

SQL> SET TIMING ON
SQL> DROP MATERIALIZED VIEW MV_T;

实体化视图已删除。

已用时间: 00: 00: 01.03
SQL> DROP MATERIALIZED VIEW LOG ON T;

实体化视图日志已删除。

已用时间: 00: 00: 00.32
SQL> DROP MATERIALIZED VIEW LOG ON T1;

实体化视图日志已删除。

已用时间: 00: 00: 00.09
SQL> DROP MATERIALIZED VIEW MV_T1;

实体化视图已删除。

已用时间: 00: 00: 00.07

虽然测试的数据量很小,但是效果已经很明显了,先删除物化视图日志然后再删除物化视图的速度要比先删除物化视图后删除物化视图日志快几十倍。

其实如果理解物化视图的刷新过程,对这个现象就不难理解了。简单的说,物化视图在删除的时候,需要在物化视图日志中清除那些只有当前物化视图需要的记录。也就是说,如果物化视图日志存在的话,物化视图在删除的时候,需要将物化视图日志中所有当前物化视图需要刷新的记录删除掉。这意味着一个DDL的语句中包含着DML的部分。因此这种方式速度慢是显然的了。

由于物化视图日志还可能被其他物化视图所使用,因此物化视图日志中删除记录只能使用DELETE语句,下面通过一个例子来证实这一点:

SQL> SET TIMING OFF
SQL> CREATE MATERIALIZED VIEW LOG ON T;

实体化视图日志已创建。

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

实体化视图已创建。

SQL> DELETE T WHERE ID != 1;

已删除50676行。

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

实体化视图已创建。

SQL> DELETE T;

已删除 1 行。

SQL> COMMIT;

提交完成。

SQL> SELECT COUNT(*) FROM MLOG$_T;

COUNT(*)
----------
50677

SQL> DROP MATERIALIZED VIEW MV_T;

实体化视图已删除。

SQL> SELECT COUNT(*) FROM MLOG$_T;

COUNT(*)
----------
1

通过这个例子可以看到,在删除物化视图MV_T时,Oracle将物化视图日志中MV_T所需的记录删除,留下了其他物化视图仍然需要的记录。

因此,对于只有一个物化视图的情况,先删除物化视图日志可以避免DML的产生,是的删除操作更加迅速。

yangtingkun 发表于:2008.04.17 23:32 ::分类: ( ORACLE ) ::阅读:(639次) :: 评论 (4)
re: 物化视图删除的顺序 [回复]

most of time even MV is obsolete, we won't drop them at all tongue

netbanker 评论于: 2008.04.19 05:50
re: 物化视图删除的顺序 [回复]

嗯,添加东西很容易,但是删除却很困难

yangtingkun 评论于: 2008.04.22 09:50
re: 物化视图删除的顺序 [回复]

杨大师,为什么我用10046跟踪物化视图快速刷新时,发现internal的sql在delete的步骤走了一个全表扫?为条件加上索引后,flush shared_pool检查v$sql_plan已经没这句了再刷,还是走全表?难道内部sql的计划是固定的?

bluetoy 评论于: 2008.07.30 10:30
re: 物化视图删除的顺序 [回复]

楼上的问题和当前的主题没有关系吧。

根据你的描述我实在没有办法判断到底是什么问题,建议你去论坛开一个帖子,详细描述一下。

yangtingkun 评论于: 2008.08.04 13:22

发表评论
标题

在此添加评论
表情符号: smile laughing tongue angry crying sad wassat wink

称呼

邮箱地址(可选)

个人主页(可选)

 authimage


切换风格
新闻聚合
博客日历
文章归档...
最新发表...
最新评论...
最多阅读文章...
最多评论文章...
博客统计...
Blog信息
网站链接...