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

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

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

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

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的产生,是的删除操作更加迅速。

Related Posts