Oracle10g增加了物化视图PCT快速刷新的支持,使用PCT快速刷新不再需要物化视图日志。
继续深入研究一下PCT快速刷新的机制。
10G物化视图PCT快速刷新不再需要物化视图日志(一):http://yangtingkun.itpub.net/post/468/463132
上一篇文章中根据执行的性能推断出物化视图的PCT刷新只针对整个分区进行的。下面通过TRACE的方式来深入研究一下,PCT刷新的工作机制:
SQL> CREATE TABLE T
2 (
3 ID NUMBER,
4 NAME VARCHAR2(30),
5 CONSTRAINT PK_T PRIMARY KEY (ID)
6 )
7 PARTITION BY RANGE (ID)
8 (
9 PARTITION P1 VALUES LESS THAN (100),
10 PARTITION P2 VALUES LESS THAN (200),
11 PARTITION P3 VALUES LESS THAN (MAXVALUE)
12 );
表已创建。
SQL> INSERT INTO T SELECT ROWNUM, OBJECT_NAME FROM DBA_OBJECTS;
已创建50642行。
SQL> CREATE MATERIALIZED VIEW MV_T REFRESH FAST AS SELECT * FROM T;
实体化视图已创建。
下面对T表进行DML和DDL,看看Oracle是如何进行PCT快速刷新的:
SQL> DELETE T PARTITION (P3) WHERE ROWNUM = 1;
已删除 1 行。
SQL> ALTER TABLE T TRUNCATE PARTITION P2;
表被截断。
SQL> ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT FOREVER, LEVEL 12';
会话已更改。
SQL> EXEC DBMS_MVIEW.REFRESH('MV_T')
PL/SQL 过程已成功完成。
SQL> ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT OFF';
会话已更改。
检查对应的TRACE文件,可以在TRACE文件中看到下面几条语句:
=====================
PARSING IN CURSOR #14 len=40 dep=0 uid=61 ct=47 lid=61 tim=50228795616 hv=227083342 ad='33703150'
BEGIN DBMS_MVIEW.REFRESH('MV_T'); END;
END OF STMT
PARSE #14:c=46875,e=125264,p=9,cr=158,cu=0,mis=1,r=0,dep=0,og=1,tim=50228795608
BINDS #14:
=====================
.
.
.
=====================
PARSING IN CURSOR #24 len=130 dep=1 uid=61 ct=7 lid=61 tim=50230157165 hv=1048116798 ad='27e7d114'
/* MV_REFRESH (DEL) */ DELETE FROM "YANGTK"."MV_T" WHERE ( ( (200 <= "ID" OR "ID" IS NULL ) OR (100 <= "ID" AND "ID" < 200) ) )
END OF STMT
PARSE #24:c=0,e=23453,p=0,cr=85,cu=0,mis=1,r=0,dep=1,og=1,tim=50230157157
BINDS #24:
WAIT #24: nam='db file scattered read' ela= 10520 file#=8 block#=6357 blocks=4 obj#=56630 tim=50230167855
WAIT #24: nam='db file sequential read' ela= 258 file#=8 block#=6361 blocks=1 obj#=56630 tim=50230209966
WAIT #24: nam='db file scattered read' ela= 3549 file#=8 block#=6362 blocks=7 obj#=56630 tim=50230224906
WAIT #24: nam='db file scattered read' ela= 644 file#=8 block#=6370 blocks=7 obj#=56630 tim=50230303504
WAIT #24: nam='db file sequential read' ela= 268 file#=8 block#=6377 blocks=1 obj#=56630 tim=50230382642
WAIT #24: nam='db file scattered read' ela= 655 file#=8 block#=6378 blocks=7 obj#=56630 tim=50230395005
=====================
.
.
.
=====================
PARSING IN CURSOR #32 len=198 dep=1 uid=61 ct=2 lid=61 tim=50231430378 hv=958674512 ad='27e7c5a4'
/* MV_REFRESH (INS) */ INSERT /*+ BYPASS_RECURSIVE_CHECK */ INTO "YANGTK"."MV_T"SELECT /*+ X_DYN_PRUNE */ "T"."ID" , "T"."NAME" FROM "T" "T" WHERE ( ( (200 <= "T"."ID" OR "T"."ID" IS NULL ) ) )
END OF STMT
PARSE #32:c=15625,e=14398,p=0,cr=79,cu=0,mis=1,r=0,dep=1,og=1,tim=50231430372
BINDS #32:
=====================
上面的第一部分是用户发出的命令,对MV_T进行快速刷新,而Oracle实际执行的步骤是后面两个部分。
Oracle进行的DELETE操作,指定了两个条件,其中(100 <= "ID" AND "ID" < 200)对应DDL中TRUNCATE的分区P2,而条件(200 <= "ID" OR "ID" IS NULL )对应的是分区P3,在执行刷新过程中,Oracle首先删除了物化视图中发生了数据变化的分区对应的数据。
随后通过INSERT语句插入P3分区对应的数据。
显然这个操作过程中,Oracle的基表操作单元为分区,也就是说PCT快速刷新的最小单位是一个分区,即使只发生了一条记录的变化,Oracle也会将整个分区删除,然后重新插入新的数据。
从上面的删除操作可以看到,对于没有发生数据修改的分区P1,Oracle在刷新的过程中并没有进行处理。
通过对TRACE文件的分析,确认了PCT的刷新是以分区为单位进行的刷新,因此这种方法应该配合物化视图日志使用,而不应该单独使用。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-329535/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/4227/viewspace-329535/