`
zhzhiqun2005
  • 浏览: 220039 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

物化视图知识入门

阅读更多
物化视图知识入门

Oracle的物化视图提供了强大的功能,可以用在不同的环境中。在不同的环境中,物化视图的作用也不相同.

数据仓库中的物化视图主要用于预先计算并保存表连接或聚集等耗时较多的操作的结果,这样,在执行查询时,就可以避免进行这些耗时的操作,而从快速的得到结果。在数据仓库中,还经常使用查询重写(query rewrite)机制,这样不需要修改原有的查询语句,Oracle会自动选择合适的物化视图进行查询,完全对应用透明。

物化视图和表一样可以直接进行查询。物化视图可以基于分区表,物化视图本身也可以分区。

除了在数据仓库中使用,物化视图还用于复制、移动计算等方面。

物化视图有很多方面和索引很相似:使用物化视图的目的是为了提高查询性能;物化视图对应用透明,增加和删除物化视图不会影响应用程序中SQL语句的正确性和有效性;物化视图需要占用存储空间;当基表发生变化时,物化视图也应当刷新。

物化视图可以分为以下三种类型:包含聚集的物化视图;只包含连接的物化视图;嵌套物化视图。三种物化视图的快速刷新的限制条件有很大区别,而对于其他方面则区别不大。

创建物化视图时可以指定多种选项,下面对几种主要的选择进行简单说明:

> 创建方式(Build Methods):包括BUILD IMMEDIATE和BUILD DEFERRED两种。BUILD IMMEDIATE是在创建物化视图的时候就生成数据,而BUILD DEFERRED则在创建时不生成数据,以后根据需要在生成数据。默认为BUILD IMMEDIATE。

> 查询重写(Query Rewrite):包括ENABLE QUERY REWRITE和DISABLE QUERY REWRITE两种。分别指出创建的物化视图是否支持查询重写。查询重写是指当对物化视图的基表进行查询时,Oracle会自动判断能否通过查询物化视图来得到结果,如果可以,则避免了聚集或连接操作,而直接从已经计算好的物化视图中读取数据。默认为DISABLE QUERY REWRITE。

> 刷新(Refresh):指当基表发生了DML操作后,物化视图何时采用哪种方式和基表进行同步。刷新的模式有两种:ON DEMAND和ON COMMIT。ON DEMAND指物化视图在用户需要的时候进行刷新,可以手工通过DBMS_MVIEW.REFRESH等方法来进行刷新,也可以通过JOB定时进行刷新。 ON COMMIT指出物化视图在对基表的DML操作提交的同时进行刷新。刷新的方法有四种:FAST、COMPLETE、FORCE和NEVER。FAST刷新采用增量刷新,只刷新自上次刷新以后进行的修改。COMPLETE刷新对整个物化视图进行完全的刷新。如果选择FORCE方式,则Oracle在刷新时会去判断是否可以进行快速刷新,如果可以则采用FAST方式,否则采用COMPLETE的方式。NEVER指物化视图不进行任何刷新。默认值是FORCE ON DEMAND。

在建立物化视图的时候可以指定ORDER BY语句,使生成的数据按照一定的顺序进行保存。不过这个语句不会写入物化视图的定义中,而且对以后的刷新也无效。

物化视图日志:如果需要进行快速刷新,则需要建立物化视图日志。物化视图日志根据不同物化视图的快速刷新的需要,可以建立为ROWID或PRIMARY KEY类型的。还可以选择是否包括SEQUENCE、INCLUDING NEW VALUES以及指定列的列表。

可以指明ON PREBUILD TABLE语句将物化视图建立在一个已经存在的表上。这种情况下,物化视图和表必须同名。当删除物化视图时,不会删除同名的表。这种物化视图的查询重写要求参数QUERY_REWRITE_INTEGERITY必须设置为trusted或者stale_tolerated。

物化视图可以进行分区。而且基于分区的物化视图可以支持分区变化跟踪(PCT)。具有这种特性的物化视图,当基表进行了分区维护操作后,仍然可以进行快速刷新操作。
对于聚集物化视图,可以在GROUP BY列表中使用CUBE或ROLLUP,来建立不同等级的聚集物化视图。



简单试验

--1.在master site上创建表和mview log
SQL> create table stu (id varchar2(10) primary key ,name varchar2(20));
Table created.
SQL> create materialized view log on stu;
Materialized view log created.

--2.在mv site上创建mview
SQL> create materialized view stu_mv refresh fast start with sysdate next sysdate+1/1440 with primary key as select * from stu@to_vm9;
Materialized view created.

SQL> select job,log_user,last_date,last_sec,next_date,next_sec,interval,what from user_jobs;
JOB LOG_USER  LAST_DATE   LAST_SEC  NEXT_DATE   NEXT_SEC   INTERVAL       WHAT                                     
--- --------- ----------- --------- ----------- ---------- -------------- -------------------------------------------
21 SEAGULL   2008-2-18 1 14:41:43  2008-2-18 1 14:42:43   sysdate+1/1440 dbms_refresh.refresh('"SEAGULL"."STU_MV"');
SQL>

SQL> select * from tab;
TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
STU_MV                         TABLE

--3.在master site上对master table做更新
SQL> INSERT INTO STU(ID,NAME) VALUES('56','555555555555');
1 row created.
SQL> commit;

--4.等1分钟后在mv site上检查
SQL> select * from stu_mv;
ID         NAME
---------- --------------------
56         555555555555


利用prebuilt mv实现跨平台,跨版本数据迁移


该方法的实现原理是对于要迁移的表对象,需要有一个主键,用于mv的刷新,对于符合该要求的表,在源表上创建mv日志,再在目标数据库上创建结构一样的表,然后在目标表上采用prebuilt方式创建mv,第一次采用完全刷新,之后采用增量刷新,等真正要切换的时候,只需要刷新完增量的日志,删除mv,保留目标表即可。




基本思路的例子:

--1.在源库上创建表和mview log
SQL> create table big_t1 as select * from dba_objects;
Table created.
SQL> select count(1) from big_t1;
  COUNT(1)
----------
      6170

SQL> create materialized view log on big_t1;
Materialized view log created.

--2.在目标数据库上创建与该表一样的表,并在该表上创建prebuilt mv
SQL> create table big_t1 as select * from big_t1@to_vm9 where 1=2;
Table created.

SQL> select count(1) from big_t1;
  COUNT(1)
----------
         0

SQL> create materialized view big_t1 on prebuilt table refresh fast as select * from big_t1@to_vm9;
Materialized view created.

--3.做完全刷新和增量刷新
SQL> exec dbms_mview.refresh('BIG_T1','Complete');
PL/SQL procedure successfully completed.
SQL> select count(1) from big_t1;
  COUNT(1)
----------
      6170
SQL>

--/*此时模拟在做完全刷新过程中,源库的表又发生了变化
SQL> insert into big_t1(object_id,owner) values(99991,'test');
1 row created.
SQL> commit;
Commit complete.    */

--再做增量刷新
SQL> select count(1) from big_t1;
  COUNT(1)
----------
      6170
    
SQL> exec dbms_mview.refresh('BIG_T1');
PL/SQL procedure successfully completed.

SQL> select count(1) from big_t1;
  COUNT(1)
----------
      6171

--4.停机切换,做最后一次刷新,然后删除源库的mview log和目标库的mview

SQL> exec dbms_mview.refresh('BIG_T1');
PL/SQL procedure successfully completed.

SQL> drop materialized view big_t1;
Materialized view dropped.

SQL> select count(1) from big_t1;
  COUNT(1)
----------
      6171

这里删除的mview(big_t1)是prebuilt mv,所以删除该mview,并不删除相应的表。
如果删除了mvnew(stu_mv),由于是普通mv,则删除了该mview,就没有对应的表了。

SQL> drop materialized view stu_mv;
Materialized view dropped.

SQL> select * from tab;
TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
BIG_T1                         TABLE
SQL>
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics