10G物化檢視PCT快速重新整理不再需要物化檢視日誌(二)

yangtingkun發表於2008-06-01

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 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)對應DDLTRUNCATE的分割槽P2,而條件(200 <= "ID" OR "ID" IS NULL )對應的是分割槽P3,在執行重新整理過程中,Oracle首先刪除了物化檢視中發生了資料變化的分割槽對應的資料。

隨後透過INSERT語句插入P3分割槽對應的資料。

顯然這個操作過程中,Oracle的基表操作單元為分割槽,也就是說PCT快速重新整理的最小單位是一個分割槽,即使只發生了一條記錄的變化,Oracle也會將整個分割槽刪除,然後重新插入新的資料。

從上面的刪除操作可以看到,對於沒有發生資料修改的分割槽P1Oracle在重新整理的過程中並沒有進行處理。

透過對TRACE檔案的分析,確認了PCT的重新整理是以分割槽為單位進行的重新整理,因此這種方法應該配合物化檢視日誌使用,而不應該單獨使用。

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-329535/,如需轉載,請註明出處,否則將追究法律責任。

相關文章