现在的位置: 首页 > 综合 > 正文

oracle 物化视图(1)——最简单的物化视图!

2013年06月28日 ⁄ 综合 ⁄ 共 4396字 ⁄ 字号 评论关闭

物化视图是一个数据库对象,它可以从一个表或者多个表中查询出所需要的数据并且将这些数据存储在表空间上。与一般的视图不同的是物化视图创建完成后,ORACLE 系统就为这个视图准备好了结果数据,那么我们再次查询该视图的时候,就是直接得到结果而不是再去查询这个表或者多个表的数据,这样就大大减少了系统资源的消耗。那么当数据源发生变化的时候(也就是 视图中的 表的内容发生变化的 时候)物化视图再重新刷新就可以了。这样我们就可以理解物化视图是为了提高查询的性能。因为物化视图他存放的是 查询的结果集,这些结果集是存放在
表空间中的,所以 物化视图是占用存储空间的。

为了方便我们理解我们首先看一下一般的视图的概念视图是查询一个或者多个表的 SELECT 语句的描述。我们来简单的创建一个视图。首先我们需要创建表,然后写一个SELECT语句 。

SQL> create table t1 (a varchar2(10),b number(10));

表已创建。

SQL> create table t2 (a varchar2(10),b number(10));

表已创建。

我们创建了两张表 t1 和t2,下面 我们 向两张表中 插入数据

SQL> insert into t1 values ('aaa','00001');

已创建 1 行。

SQL> insert into t1 values ('bbb','00002');

已创建 1 行。

SQL> insert into t2 values ('aa1','00002');

已创建 1 行。

SQL> insert into t2 values ('bb1','00003');

已创建 1 行。

SQL> commit;

提交完成。

我们分别 两张表中插入了两行数据,然后我们写一个查询语句,然后我们创建一个试图,视图的名称为v1

SQL> select t1.a,t2.b from t1,t2 where t1.b=t2.b;

A                   B
---------- ----------
bbb                 2

SQL> create view v1 as select t1.a,t2.b from t1,t2 where t1.b=t2.b;

视图已创建。
SQL> select * from v1;

A                   B
---------- ----------
bbb                 2

可以看到我们查询视图的结果和查询 那个SELECT 语句的结果是一致的,说明视图是查询一个或者多个表的 SELECT 语句的描述,相信这句话 大家都能理解了。我们 查询 一下 我们创建的视图

SQL> select OBJECT_NAME,OBJECT_TYPE,CREATED,STATUS from user_objects where  OBJECT_NAME = 'V1';

OBJECT_NAM OBJECT_TYPE         CREATED        STATUS
---------- ------------------- -------------- -------
V1         VIEW                05-3月 -12     VALID

我们 可以 通过 ORACLE 提供的 包 DBMS_METADATA.GET_DDL 来查询出 创建视图的脚本

SQL> select dbms_metadata.get_ddl('VIEW','V1') from dual;

DBMS_METADATA.GET_DDL('VIEW','V1')
--------------------------------------------------------------------------------

  CREATE OR REPLACE FORCE VIEW "U1"."V1" ("A", "B") AS
  select t1.a,t2.b from

那么视图 我想 我们应该理解了 视图 方便程序员的开发 但是 视图的应用的局限性很小 ,实际上 ORACLE 在做视图 查询的 时候 也就是 转换为SQL 语句的查询 这样 并没有整体性能的提高。我们 再来 理解物化视图,下面 我们 开始创建 物化视图 (这里 我们创建的实体视图 不是自动刷新 而是需要手动去刷新)

SQL> create materialized view v2 as select t1.a,t2.b from t1,t2 where t1.b=t2.b;

实体化视图已创建。

SQL> select * from v2;

A                   B
---------- ----------
bbb                 2

物化视图 从某种意义上说 是一张物理 表 可以通过 DBA_TABLES 进行查询我们 来 论证一下

SQL> select TABLE_NAME,TABLESPACE_NAME,STATUS from user_tables where TABLE_NAME = 'V2';

TABLE_NAME                     TABLESPACE_NAME                STATUS
------------------------------ ------------------------------ --------
V2                             USERS                          VALID

从 DBA_TABLES 视图中 我们可以看出 实体视图 可以通过 TABLE_NAME 字段 这个条件 来选择 同时 物化视图 有自己对应的表空间,我们 来查询一下 刚才创建的 视图 v1

SQL> select TABLE_NAME,TABLESPACE_NAME,STATUS from user_tables where TABLE_NAME = 'V1';

未选定行

可以看出 普通视图 在 DBA_TABLES 中 是没有记录的,也没有对应的表空间。物化视图 会占用 一定的 存储空间 因为 它 存放了查询的结果集 那么 它也是一种段,可以再 DBA_SEGMENTS 中查询出我们来做个测试

SQL> select SEGMENT_NAME,SEGMENT_TYPE,TABLESPACE_NAME from dba_segments where SEGMENT_NAME = 'V1';

未选定行

SQL> select SEGMENT_NAME,SEGMENT_TYPE,TABLESPACE_NAME from dba_segments where SEGMENT_NAME = 'V2';

SEGMENT_NAME                                                                      SEGMENT_TYPE       TABLESPACE_NAME
--------------------------------------------------------------------------------- ------------------ ------------------------------
V2                                                                                TABLE              USERS

下面 我们更新一下 t2 表 中的 信息 看一下 物化视图的变化信息

SQL> insert into t2 values ('ccc','00001');

已创建 1 行。

SQL> commit;

提交完成。
SQL> select * from v1;

A                   B
---------- ----------
bbb                 2
aaa                 1

SQL> select * from v2;

A                   B
---------- ----------
bbb                 2

可以看出 物化视图的信息 没有发生变化,因为 我们在创建 物化视图的 时候 我们没有指定该视图的刷新方法和刷新模式,所以创建完 该实体视图,该视图默认的刷新方法和刷新模式为 FORCE和DEMAND。我们可以通过 user_mviews 这个 视图 查询 我们创建的 实体视图的信息

SQL> select MVIEW_NAME,REFRESH_MODE,REFRESH_METHOD from user_mviews where MVIEW_NAME = 'V2';

MVIEW_NAME                     REFRES REFRESH_
------------------------------ ------ --------
V2                             DEMAND FORCE

这里 默认的 是 手工刷新,所以 在这里 我们对物化视图进行更新

SQL> exec dbms_mview.refresh('V2');

PL/SQL 过程已成功完成。
SQL> select * from v2;

A                   B
---------- ----------
bbb                 2
aaa                 1

这 说明了 基表的 数据 发生变化,那么 物化视图的 内容 也将 被写入到 对应的存储空间中。我们 也可以 创建 自动更新的 物化视图

SQL> create materialized view v3 refresh force on commit as select t1.a,t2.b from t1,t2 where t1.b=t2.b;

实体化视图已创建。

可以看出 已经成功创建,我们现在向 表中插入 数据 来查看物化视图的变化情况

SQL> insert into t1 values ('ccc','00003');

已创建 1 行。

SQL> commit;

提交完成。

SQL> select * from v1;

A                   B
---------- ----------
bbb                 2
ccc                 3
aaa                 1

SQL> select * from v2;

A                   B
---------- ----------
bbb                 2
aaa                 1

SQL> select * from v3;

A                   B
---------- ----------
bbb                 2
ccc                 3
aaa                 1

刷新(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。

刷新物化视图:
exec dbms_mview.refresh('MV_PARTITIONS','C');  --完整刷新
exec dbms_mview.refresh('MV_PARTITIONS','F');  --增量刷新

SQL> select MVIEW_NAME,REFRESH_MODE,REFRESH_METHOD from user_mviews;

MVIEW_NAME                     REFRES REFRESH_
------------------------------ ------ --------
V2                             DEMAND FORCE
V3                             COMMIT FORCE

抱歉!评论已关闭.