Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2885536
  • 博文数量: 599
  • 博客积分: 16398
  • 博客等级: 上将
  • 技术积分: 6875
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-30 12:04
个人简介

WINDOWS下的程序员出身,偶尔也写一些linux平台下小程序, 后转行数据库行业,专注于ORACLE和DB2的运维和优化。 同时也是ios移动开发者。欢迎志同道合的朋友一起研究技术。 数据库技术交流群:58308065,23618606

文章分类

全部博文(599)

文章存档

2014年(12)

2013年(56)

2012年(199)

2011年(105)

2010年(128)

2009年(99)

分类: Oracle

2009-11-30 12:50:30

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表进行DMLDDL,看看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 oct=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 oct=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 oct=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)对应DDLTRUNCATE的分区P2,而条件(200 <= "ID" OR "ID" IS NULL )对应的是分区P3,在执行刷新过程中,Oracle首先删除了物化视图中发生了数据变化的分区对应的数据。

随后通过INSERT语句插入P3分区对应的数据。

显然这个操作过程中,Oracle的基表操作单元为分区,也就是说PCT快速刷新的最小单位是一个分区,即使只发生了一条记录的变化,Oracle也会将整个分区删除,然后重新插入新的数据。

从上面的删除操作可以看到,对于没有发生数据修改的分区P1Oracle在刷新的过程中并没有进行处理。

通过对TRACE文件的分析,确认了PCT的刷新是以分区为单位进行的刷新,因此这种方法应该配合物化视图日志使用,而不应该单独使用。

阅读(2320) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~