yangtingkun
===========================================================
基于COMMIT SCN的物化视图日志如何支持快速刷新(二)
===========================================================

11.2中物化视图日志可以指定COMMIT SCN,这时物化视图刷新就不需要时间戳了,这篇简单描述Oracle是如何实现通过COMMIT SCN来进行刷新的。

这一篇继续分析Oracle是如何实现快速刷新的。

基于COMMIT SCN的物化视图日志如何支持快速刷新(一):http://yangtingkun.itpub.net/post/468/497439


从上一篇得到的TRACE不难发现,物化视图快速刷新由原来的3SQL,变成了现在的2条。INSERTUPDATE语句被合并为一个MERGE语句。

首先来看DELETE语句:

DELETE FROM "TEST"."MV_T" SNAP$
WHERE "ID" IN
(
SELECT DISTINCT LOG$."ID"
FROM
(
SELECT MLOG$."ID"
FROM "TEST"."MLOG$_T" MLOG$ , ALL_SUMMAP MAP$
WHERE MLOG$.XID$$ = MAP$.XID
AND MAP$.COMMIT_SCN > :1
AND MAP$.COMMIT_SCN <= :2
AND ("DMLTYPE$$" != 'I')
) LOG$
WHERE (LOG$."ID") NOT IN
(
SELECT MAS_TAB$."ID"
FROM "T" "MAS_TAB$"
WHERE LOG$."ID" = MAS_TAB$."ID"
)
)

/* MV_REFRESH (MRG) */
MERGE INTO "TEST"."MV_T" "SNA$"
USING
(
SELECT CURRENT$."ID",CURRENT$."NAME",CURRENT$."AGE"
FROM
(
SELECT "T"."ID" "ID","T"."NAME" "NAME","T"."AGE" "AGE"
FROM "T" "T"
) CURRENT$,
(
SELECT DISTINCT MLOG$."ID"
FROM "TEST"."MLOG$_T" MLOG$, ALL_SUMMAP MAP$
WHERE MLOG$.XID$$ = MAP$.XID
AND MAP$.COMMIT_SCN > :1
AND MAP$.COMMIT_SCN <= :2
AND ("DMLTYPE$$" != 'D')
) LOG$
WHERE CURRENT$."ID" = LOG$."ID"
)"AV$"
ON ("SNA$"."ID" = "AV$"."ID")
WHEN MATCHED THEN UPDATE
SET "SNA$"."ID" = "AV$"."ID","SNA$"."NAME" = "AV$"."NAME","SNA$"."AGE" = "AV$"."AGE"
WHEN NOT MATCHED THEN INSERT
(SNA$."ID",SNA$."NAME",SNA$."AGE")
VALUES (AV$."ID",AV$."NAME",AV$."AGE")

虽然是3条语句变成了2条,但是从SQL的目的看,和时间戳的物化视图刷新并没有本质的不同。由于不再使用时间戳而改为利用COMMIT SCN,因此Oracle引入了一个辅助表ALL_SUMMAP,通过ALL_SUMMAPXID转化为对应的SCN

下面简单看看ALL_SUMMAP的特性:

SQL> SELECT * FROM ALL_SUMMAP;

XID COMMIT_SCN
---------------- ----------------
2533498128696031 1112622614013

SQL> SELECT * FROM MLOG$_T;

未选定行

SQL> UPDATE T SET NAME = 'TEST' WHERE ID = 10;

已更新 1 行。

SQL> COMMIT;

提交完成。

SQL> SELECT * FROM MLOG$_T;

ID D O CHANGE_VECTOR$$ XID$$
---------------- - - ------------------------------ ----------------
10 U U 04 2814848551361701

SQL> SELECT * FROM ALL_SUMMAP;

XID COMMIT_SCN
---------------- ----------------
2814848551361701 1112622655597
2533498128696031 1112622614013

SQL> DELETE T WHERE ID = 10;

已删除 1 行。

SQL> COMMIT;

提交完成。

SQL> SELECT * FROM ALL_SUMMAP;

XID COMMIT_SCN
---------------- ----------------
2814848551361701 1112622655597
1970586829980189 1112622655626
2533498128696031 1112622614013

SQL> SELECT * FROM MLOG$_T;

ID D O CHANGE_VECTOR$$ XID$$
---------------- - - ------------------------------ ----------------
10 U U 04 2814848551361701
10 D O 00 1970586829980189

SQL> EXEC DBMS_MVIEW.REFRESH('MV_T')

PL/SQL 过程已成功完成。

SQL> SELECT * FROM ALL_SUMMAP;

XID COMMIT_SCN
---------------- ----------------
2814848551361701 1112622655597
1970586829980189 1112622655626
2533498128696031 1112622614013

SQL> CREATE TABLE T_TEST (ID NUMBER PRIMARY KEY);

表已创建。

SQL> CREATE MATERIALIZED VIEW LOG ON T_TEST WITH COMMIT SCN;

实体化视图日志已创建。

SQL> INSERT INTO T_TEST VALUES (1);

已创建 1 行。

SQL> SELECT * FROM MLOG$_T_TEST;

ID D O CHANGE_VECTOR$$ XID$$
---------------- - - ------------------------------ ----------------
1 I N FE 2815041824890019

SQL> SELECT * FROM ALL_SUMMAP;

XID COMMIT_SCN
---------------- ----------------
2814848551361701 1112622655597
1970586829980189 1112622655626
2533498128696031 1112622614013

SQL> CREATE MATERIALIZED VIEW MV_T_TEST
2 REFRESH FAST
3 AS SELECT *
4 FROM T_TEST;

实体化视图已创建。

SQL> SELECT * FROM ALL_SUMMAP;

XID COMMIT_SCN
---------------- ----------------
2814848551361701 1112622655597
1970586829980189 1112622655626
2815041824890019 1112622655813
2533498128696031 1112622614013

从上面的一系列的测试可以看到,ALL_SUMMAP中的记录对应的是物化视图需要刷新的每个事务。如果没有建立物化视图,只是包含物化视图日志,这时基表的修改不会导致ALL_SUMMAP中新增记录。而每个物化视图需要刷新的每个记录都会在这个表增加一条记录。

因此物化视图刷新的时候只需要刷新SCN大于上次刷新的SCN的修改,就可以确保刷新到最新的状态。

yangtingkun 发表于:2010.03.14 23:00 ::分类: ( ORACLE ) ::阅读:(687次) :: 评论 (0)

发表评论
标题

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

称呼

邮箱地址(可选)

个人主页(可选)

 authimage


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