Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2796690
  • 博文数量: 389
  • 博客积分: 4177
  • 博客等级: 上校
  • 技术积分: 4773
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-16 23:29
文章分类

全部博文(389)

分类: Oracle

2014-02-15 15:44:32

                                       MV的Synchronous Reresh
                             
   传统的fast refresh通过在base表上增加一个触发器,当对表进行dml操作时,同时也有相关的记录
被insert到mv log表里。当mv以on commit模式定义时,在对mv的更新同时也对mv同时进行了更新,这样
的好处是mv和base的数据实时保持一致,但是对事务的响应时间形成很重要的影响.

  在12C中oracle针对DW的环境引入了一种全新的刷新模式称为synchronous refresh(下文简称synch refresh)。
synchronous的主要的思想是时同时更新base和mv,这也是synchronous的名称来源。

  synch refresh使的场景有以下特定的假设.一般认为在从外部加载数据到DW中表的时候,会经过清洗,合规
检查等等。首先会把外部的数据加载到一个中间表(有时候也称为staging area),在进行了相应的处理后,然后
再加载到DW的相应的表,一般是通过exchange partition操作.

  synch refresh要求基表必须是range分区或复分分区且顶层分区是以range方式进行分区,必须要主键。其
mv的分区方式和表一致.synch refresh也有类似fash refresh一样的mv log,不过称为staging log.在fash
refresh的mv log中的数据由oracle中的trigger进行填充,而staging log由人工去填充,充当的角色相当于
DW数据表中的staging area。

  来看一个例子.假设有表t1,根据字段a,以range分区,且a是primary key

SQL> create table t1
  2  (a int,
  3   b int)
  4  partition by range(a)
  5  (partition p0 values less than (10),
  6   partition p1 values less than (20),
  7  partition p2 values less than (30));

Table created.

SQL> alter table t1 add primary key (a)

Table altered.

在表t1上创建staging log,指定st_t1为staging log的表名

SQL> create materialized view log on t1 for synchronous refresh using st_t1;

Materialized view log created.


创建mv
SQL> create materialized view mv_t1
  2  partition by range(a)
  3  (partition p0 values less than (10),
  4   partition p1 values less than (20),
  5  partition p2 values less than (30))
  6  REFRESH USING TRUSTED CONSTRAINTS
  7  as
  8  select a,sum(b) from t1 group by a;

Materialized view created.

sum(b)和直接select b没有区别,因为a是主健,这里仅是例子


SQL> select * from t1;  

no rows selected

SQL> select * from mv_t1;

no rows selected

现在已经建好和mv,但是都没有数据.不过还需要把mv注册成sync refresh的方式,对于sync refresh
oracle提供了一个全新的dbms_sync_refresh包用来执行相关的操作

SQL> execute dbms_sync_refresh.register_mviews('MV_T1');

PL/SQL procedure successfully completed.


接下来需要做是的直接对st_t1表进行insert数据,这一步相当于在DW的数据加载到staging area的阶段。
只是数据已经被insert到st_t1表中了,而不是原来自定义的专用表

SQL> insert into st_t1(dmltype$$,a,b) values('I',15,1);
SQL> insert into st_t1(dmltype$$,a,b) values('I',5,1);
SQL> insert into st_t1(dmltype$$,a,b) values('I',25,1);
SQL> commit; 

准备staging_log和刷新mv

SQL> exec dbms_sync_refresh.prepare_staging_log('C##FRANK','T1');
PL/SQL procedure successfully completed.

SQL> exec dbms_sync_refresh.prepare_refresh(dbms_sync_refresh.get_group_id('MV_T1'));
PL/SQL procedure successfully completed.

刷新mv
SQL> exec dbms_sync_refresh.execute_refresh(dbms_sync_refresh.get_group_id('MV_T1'));
PL/SQL procedure successfully completed.

现在再看两个表的数据
SQL> select * from t1;
         A          B
---------- ----------
         5          1
        15          1
        25          1

SQL> select * from mv_t1;  
         A     SUM(B)
---------- ----------
         5          1
        15          1
        25          1

可以看到mv中的数据和base表中的数据一致的,其实质是两者都是通过exchange partition操作来形成最新的数据。
通过sync refresh主要的好处是在加载到DW中表的时候,同时也通过exchange partition更新了mv的数据,相比fast
refresh在计算后通过merge迁移到mv中的方式要快得多,不好的地方是使用场景有限,其他还有一些限制,具体可以
参考相关的oracle data warehousing guide.

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