`
fyd222
  • 浏览: 103904 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

ORACLE物化视图--循序渐进MView(二) MView Log的结构与快速刷新

 
阅读更多

 



前言

现在我们通过一些例子来说明一下MView Log的基本结构以及MView快速刷新的过程。

在这一部分里面,我们还是利用上一部分提供的例子先建立一个MView,同时也创建该MView基表的MView Log。

-- 创建一个测试用的表T
USER@orcl> create table t (a int, b varchar2(50), constraint pk_tprimary key(a));
Table created.
 
-- 创建对应的MV名为MVT
USER@orcl> create materialized view mvt as select * from t;
Materialized view created.
 
-- 现在往表里面插入一些个数据
USER@orcl> insert into t select rownum, object_name fromall_objects;
11449 rows created.
 
USER@orcl> commit;
Commit complete.
 
-- 下面对mview做一次刷新看看
USER@orcl> exec dbms_mview.refresh('mvt');
PL/SQL procedure successfully completed.
 
-- 创建MView Log
USER@orcl> create materialized view log on t;
Materialized view log created.
 
-- 接下来就是进行快速刷新了
USER@orcl> exec dbms_mview.refresh('mvt', 'F');
PL/SQL procedure successfully completed.

 


MView Log的结构

我们先看一下两个测试表的MView Log的结构:

-- 含有PK的MView
USER@orcl> desc mlog$_t;
 Name                 Null?    Type
 -------------------- -------- --------------
 A                             NUMBER
 SNAPTIME$$                    DATE
 DMLTYPE$$                     VARCHAR2(1)
 OLD_NEW$$                     VARCHAR2(1)
 CHANGE_VECTOR$$               RAW(255)

现在我们挨个说一下各列的含义:

A
这个我们基表T的主键列,如果基表的主键是一个复合索引的话那这里也就存在多个和基表定义一样的列,当基表被修改以后,基表的主键就会被记录到这个列里面。
SNAPTIME$$
用来记录MView刷新的时间,这个字段只有在一个基表对应一个以上的MView的时候才有意义,因为对于一个MView Log来说,只有当所有的MView都刷新完了以后才能把MView Log里面的记录删除,当一个MView刷新的时候,它会把此列置成该MView刷新的时候,在这个MView再次刷新的时候,那些上次刷新过的列就不用再次被刷新了。

下面我们用一个例子来说明一下:

-- 在建立一个基于表T的MView MVT2
USER@orcl> create materialized view mvt2 as select * from t;
Materialized view created.
 
-- 先做一次刷新
USER@orcl> exec dbms_mview.refresh('mvt2');
PL/SQL procedure successfully completed.
 
-- 现在对表T做一些修改
USER@orcl> update t set b=upper(b) where rownum<5;
 
4 rows updated.
 
-- 现在看看MView Log的记录
USER@orcl> select * from mlog$_t;
 
         A SNAPTIME$$          D O CHANGE_VEC
---------- ------------------- - - ----------
       936 4000-01-01 00:00:00 U U 04
       937 4000-01-01 00:00:00 U U 04
       938 4000-01-01 00:00:00 U U 04
       939 4000-01-01 00:00:00 U U 04
 
-- 现在我们刷新MVT
USER@orcl> exec dbms_mview.refresh('mvt','f');
 
PL/SQL procedure successfully completed.
 
-- 我们可以看到SNAPTIME$$时间变了
USER@orcl> select * from mlog$_t;
 
         A SNAPTIME$$          D O CHANGE_VEC
---------- ------------------- - - ----------
       936 2009-02-18 07:28:09 U U 04
       937 2009-02-18 07:28:09 U U 04
       938 2009-02-18 07:28:09 U U 04
       939 2009-02-18 07:28:09 U U 04
 
-- 对比一下MVT的LAST_REFRESH_DATE,我们可以发现这个是一样的
USER@orcl> select MVIEW_NAME, LAST_REFRESH_DATE from dba_mviewswhere mview_name in ('MVT', 'MVT2');
 
MVIEW_NAME                     LAST_REFRESH_DATE
------------------------------ -------------------
MVT                            2009-02-18 07:28:09
MVT2                           2009-02-18 07:27:19
DMLTYPE$$
用于表示DML操作类型,I表示INSERT,D表示DELETE,U表示UPDATE,这个我们可以从上面的例子里面得到验证。
OLD_NEW$$
用于表示这个值是新值还是旧值。N(EW)表示新值,O(LD)表示旧值,U表示UPDATE操作。
CHANGE_VECTOR$$
表示修改矢量,用来表示被修改的是哪个或哪几个字段,用二进制的方式来保存修改列的结果。
USER@orcl> create table ttt (a int, b varchar(40), c varchar(40));
 
Table created.
 
USER@orcl> alter table ttt add constraint pk_ttt primary key(a);
 
Table altered.
 
USER@orcl> insert into ttt select rownum, object_name, object_namefrom all_objects;
 
11488 rows created.
 
USER@orcl> commit;
 
Commit complete.
 
USER@orcl> create snapshot mvttt as select * from ttt;
 
Materialized view created.
 
USER@orcl> create snapshot log on ttt;
 
Materialized view log created.
 
USER@orcl> commit;
 
Commit complete.
 
USER@orcl> update ttt set b=upper(b) where rownum<5;
 
4 rows updated.
 
USER@orcl> update ttt set c=upper(c) where rownum<5;
 
4 rows updated.
 
USER@orcl> update ttt set b=upper(b), c=upper(c) where rownum<5;
 
4 rows updated.
 
USER@orcl> select * from mlog$_ttt;
 
         A SNAPTIME$$          D O CHANGE_VEC
---------- ------------------- - - ----------
       253 4000-01-01 00:00:00 U U 04
       254 4000-01-01 00:00:00 U U 04
       255 4000-01-01 00:00:00 U U 04
       256 4000-01-01 00:00:00 U U 04
       253 4000-01-01 00:00:00 U U 08
       254 4000-01-01 00:00:00 U U 08
       255 4000-01-01 00:00:00 U U 08
       256 4000-01-01 00:00:00 U U 08
       253 4000-01-01 00:00:00 U U 0C
       254 4000-01-01 00:00:00 U U 0C
       255 4000-01-01 00:00:00 U U 0C
       256 4000-01-01 00:00:00 U U 0C

从上面的例子我们可以看出,修改列B的CHANGE_VECTOR$$是04(0100),修改列C的CHANGE_VECTOR$$值是08(1000),同时修改这两个列就变成了0C(1100)。


刷新的过程


完全刷新的过程

在Oracle 9i以及以前版本中,MView的完全刷新是先对数据库基表做一个truncate操作然后再将基表的数据全部插入到MView中,而Oracle 10g中,MView完全刷新之前并不对MView进行truncate的操作,取而代之的是delete操作,这个在操作大量的数据的时候会有很大的影响,这一点可以通过开trace来看到,这里就不在贴实验的具体过程了。


快速刷新过程

看了MView Log的结构之后我们很容易就能理解MView快速刷新的基本原理了:首先在对基表做update、delete、insert操作之后,隐藏的触发器会把基表的修改记录到MView Log中,在MView Log中基表的主键会被记录(仅对于基于PK的MView来说,其他类型的MView随后介绍),这个记录的pk会在MView做快速刷新的时候被用来定位被操作的数据行,同时还有一些其他的数据会被记录。

在MView做快速刷新的时候,对于不同的操作语句会有一点点不一样的地方:

insert操作
通过MView Log记录的基表的主键数据以及DMLTYPE$$字段我们知道那些行是行是新插入的,只要将这些新数据导入到MView中即可。
delete操作
同样通过MView Log记录的基表的主键数据以及DMLTYPE$$字段我们知道那些行是行是被删除了的,只要将这些在基表被删除掉的数据在MView中删除掉即可。
update操作
通过MView Log记录的基表的主键,DMLTYPE$$字段以及CHANGE_VECTOR$$我们知道那些行的那些列进行了更新的操作,然后再依照基表的数据对MView中相应的列挨个进行刷新操作。

下面我们利用上面的MVTTT进行一下update操作的实验,主要是验证update的时候Oracle是否只会update基表中被修改的列:
首先我们建立一个对MView MVTTT中列C的触发器,在当C列被修改以后在一个新表中插入一条记录。

-- 创建一个记录表
USER@orcl> create table ttt_t(a timestamp default sysdate, bvarchar(10));
Table created.
 
-- 创建相应的触发器
USER@orcl>
    CREATE OR REPLACE TRIGGER tri_mvttt
    BEFORE INSERT OR DELETE OR UPDATE OF c ON ttt
    FOR EACH ROW
    BEGIN
        INSERT INTO ttt_t VALUES(SYSDATE, 'c');
    END tri_mvttt;
    /
 
Trigger created.

现在我们对基表的列b做一次更新的操作,看看刷新MView以后表TTT_T中是否有数据

USER@orcl> update ttt set b=upper(b) where rownum<5;
4 rows updated.
 
USER@orcl> select * from mlog$_ttt;
         A SNAPTIME$$          D O CHANGE_VEC
---------- ------------------- - - ----------
       253 4000-01-01 00:00:00 U U 04
       254 4000-01-01 00:00:00 U U 04
       255 4000-01-01 00:00:00 U U 04
       256 4000-01-01 00:00:00 U U 04
 
-- 做一次快速刷新
USER@orcl> exec dbms_mview.refresh('mvttt', 'f');
PL/SQL procedure successfully completed.
 
-- 我们可以看到TTT_T里面是没有数据的
USER@orcl> select * from ttt_t;
no rows selected

接着我们再对对基表的列c做一次更新的操作,看看刷新MView以后表TTT_T中是否有数据

USER@orcl> update ttt set c=upper(c) where rownum<5;
4 rows updated.
 
USER@orcl> select * from mlog$_ttt;
         A SNAPTIME$$          D O CHANGE_VEC
---------- ------------------- - - ----------
       253 4000-01-01 00:00:00 U U 08
       254 4000-01-01 00:00:00 U U 08
       255 4000-01-01 00:00:00 U U 08
       256 4000-01-01 00:00:00 U U 08
 
-- 做一次快速刷新
USER@orcl> exec dbms_mview.refresh('mvttt', 'f');
PL/SQL procedure successfully completed.
 
-- 这回我们可以看到数据了
USER@orcl> select * from ttt_t;
 
A                                B
------------------------------   ----------
18-FEB-09 01.16.53.000000 PM     c
18-FEB-09 01.16.53.000000 PM     c
18-FEB-09 01.16.53.000000 PM     c
18-FEB-09 01.16.53.000000 PM     c

注意:对于基表的每一次update操作都会被记录到MView Log中,不管更新的是否是同一行的同一列,而这些操作也会在MView中被一一的推一遍,一个不拉的,这样如果一个MView操作很频繁而且刷新的间隔太长了的话快速刷新也是很痛苦的一件事的。

分享到:
评论

相关推荐

    oracle物化视图_循序渐进学习笔记

    在本篇循序渐进的学习笔记中,我们将深入探讨物化视图的概念、用途、刷新机制及其相关问题。 首先,我们需要了解几个关键术语。基表是创建物化视图时引用的原始数据表或视图,而物化视图(MView)则是基于这些基表...

    Oracle物化视图应用详解

    Oracle物化视图是一种数据库对象,它存储了查询结果,以提供快速的数据访问,特别适合于需要频繁查询但计算过程复杂或涉及大量数据连接的场景。物化视图的使用可以显著提高查询性能,因为它避免了每次查询时的计算...

    Oracle数据库中物化视图的原理剖析

    在Oracle 10g之前,要检查物化视图是否配置正确,需要使用DBMS_MVIEW包的EXPLAIN_MVIEW和EXPLAIN_REWRITE过程,这些过程只能简单地表明某个特性(如快速刷新或查询重写)可能适用于物化视图,但不会提供具体实现建议...

    oracle 物化视图详解(内含例子)

    2. **ONCOMMIT**:当基表的数据发生更改并且事务提交后,Oracle会立即刷新物化视图,以保持其数据与基表的一致性。这种方式适合于数据频繁变化且对数据实时性要求较高的情况。 #### 三、物化视图的创建示例及解释 ...

    ORACLE使用物化视图和查询重写功能

    - **快速刷新**:使用`TUNE_MVIEW`功能来提高物化视图的刷新速度。 #### 七、总结 通过本教程的学习,我们不仅掌握了物化视图和查询重写的基本原理及其在Oracle数据库中的实现方法,而且还深入了解了如何通过一...

    oracle物化视图资料

    #### 二、物化视图与普通视图的区别 - **存储方式**:普通视图不实际存储数据,只是保存了一个查询定义;而物化视图则实际在表空间中存储了查询结果。 - **查询性能**:由于普通视图在每次查询时都需要重新计算,...

    oracle物化视图

    【Oracle物化视图】是Oracle数据库中一种特殊的数据对象,它存储了查询结果集的物理副本,可以提供对远程数据的快速访问和一致性保证。物化视图的主要优点在于,它可以减少对远程数据源的访问,提高数据的本地可用性...

    oracle的物化视图

    `ON DEMAND`意味着物化视图在用户需要时才进行刷新,可以手动或定时通过DBMS_MVIEW.REFRESH等过程触发。`ON COMMIT`则是在对基表的DML操作提交时同步刷新。刷新方法包括`FAST`、`COMPLETE`、`FORCE`和`NEVER`,其中`...

    Oracle中管理物化视图变得更加容易

    1. **快速刷新**:物化视图可以设置为快速刷新,这意味着当基础表的数据发生变化时,物化视图能够迅速更新,以保持与源数据的一致性。有两种刷新方式:完全刷新(Full Refresh)和增量刷新(Fast Refresh)。完全...

    Oracle数据库中物化视图的原理剖析.pdf

    快速刷新依赖于物化视图日志(Materialized View Log),这是一个特殊的表,记录了基础表中的行变化,使得物化视图能够跟踪并仅更新必要的部分。 创建物化视图时,可以通过`REFRESH FAST`选项启用快速刷新,如示例...

    一个物化视图的简单例子

    3. **启用物化视图日志**:为了支持物化视图的快速刷新,需要在基础表上启用物化视图日志(Materialized View Log)。这样,数据库就可以记录对基础表的所有修改操作,以便在刷新物化视图时仅更新变化的部分,而不是...

    使用物化视图和exp实现生产库的逻辑实时备份

    本文主要探讨了如何利用Oracle数据库中的物化视图技术和逻辑备份工具`exp`来实现生产库个别表的实时数据刷新与备份。这种方法不仅能够确保数据的安全性,还能满足实时性需求,适用于那些对数据新鲜度有较高要求的...

    OCM考试实验笔记之一_物化视图.pdf

    `REFRESH FAST ON COMMIT`选项则表示当事务提交时,物化视图会快速刷新,以保持与源表同步。例如: ```sql CREATE MATERIALIZED VIEW mv1 (aid, bid, aid2, bid2, acc) BUILD IMMEDIATE REFRESH FAST ON COMMIT ...

    oracle数据快照

    #### 二、Oracle 物化视图日志(Materialized View Log) 在上述部分内容中,多次出现了 `CREATE MATERIALIZED VIEW LOG` 的语句。这涉及到 Oracle 的一种特殊功能——物化视图日志(Materialized View Log,简称 ...

    Oracle数据仓库实体化视图的研究与应用

    ### Oracle数据仓库实体化视图的研究与应用 #### 摘要 本文深入探讨了Oracle数据仓库中的实体化视图(Materialized View)及其在实际应用中的重要性。通过研究,我们发现实体化视图是一种有效管理概要数据的方法,...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

     删除HKEY_LOCAL_MACHINE/SYSETM/CurrentControlSet/Services/Eventlog/application中所有以oracle开头的键。  删除HKEY_CLASSES_ROOT目录下所有以Ora、Oracle、Orcl或EnumOra为前缀的键。  删除HKEY_CURRENT_...

    mview-src-0.3.2.tar.gz

    【压缩包子文件的文件名称列表】: mview-src-0.3.2 这个列表表明压缩包内包含的是mview源代码的完整文件结构。通常,一个开源项目的源代码会包含以下部分: 1. **README** 文件:提供项目的基本信息,安装指南,...

Global site tag (gtag.js) - Google Analytics