一、理解物化视图的作用

1,在分布式的海量数据环境中,信息查询的速度问题显得尤为重要。传统的查询方式,即根据用户的要求,每次都重新的进入基表或视图查询,所需要的时间太长。

例如移动通信行业,即使客户需要查询很少的信息,也可能会药费很多时间,可能在30分钟左右,如果数据库主机稍有繁忙,这个时间会更长,客户难以忍受,为了解决这种问题,ORACLE 中设计了物化视图(以称为 MV)

2,提高查询速度,数据库性能调整的重点:

2-1,调整 sga 和 pga 的内存

2-2,调整 sql 语句,使用绑定变量

2-3,使用物化视图

2-4,系统结构上,使用读写分离。11g 提供的 DG 的新功能,读库与写库的实时更新

如果不使用 11g 的新功能,可以在写库上使用 logmnr 实现日志挖掘,传输到读库上,重做日志;在读库、写库之间使用 queue;

3,物化视图是包括一个查询结果的数据库对象,它是远程数据的本地副本,或者用来生成基于数据表求和的汇总表。物化视图存储基于远程表的数据,也可以称为快照

3-1,物化视图可以查询表,视图和其它的物化视图。通常情况下,物化视图被称为主表(在复制期间)或明细表(在数据仓库中)。

4,oracle 的复制技术:物化视图、DG、消息队列

5,视图和物化视图的区别:视图中的数据是不存在,物化视图中的数据是实际存在

6,对于复制,物化视图允许你在本地维护远程数据的副本,这些副本是只读的。如果你想修改本地副本,必须使用高级复制的功能。当你想从一个表或视图中抽取数据时,你可以从物化视图中抽取

7,对于数据仓库,创建的物化视图通常情况下是聚合视图,单一表聚合视图和连接视图。

8,物化视图有很多方面和索引很相似:使用物化视图的目的是为了提高查询性能;物化视图对应用透明,增加和删除物化视图不会影响应用程序中 SQL 语句的正确性和有效性;

9,物化视图需要占用存储空间,当基表发生变化时,物化视图也应当刷新。

10,物化视图的作用

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

10-2,数据仓库中的物化视图主要用于预先计算并保存表连接或聚集等耗时较多的操作的结果,这样,在执行查询时,就可以避免进行这些耗时的操作,快速的得到结果

在数据仓库中,还经常使用查询重写(query rewrite)机制,这样不需要修改原有的查询语句,Oracle 会自动选择合适的物化视图进行相询,完全对应用透明

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

二、了解 mlog$_ 视图和 rupd$_ 视图的作用

1,mlog$_ 这个是日志表

2,rupd$_这个是支持可更新的表

三、掌握 11g 的物化视图的选项的作用

1,查询重写(Query Rewrite):包括 ENABLE QUERY REWRITE 和 DISABLE QUERY REWRITE 两种。分别指创建的物化视图是否支持查询重写。

查询重写是指当对物化视图的基表进行查询时,Oracle 会自动判断能否通过查询物化视图来得到结果。默认为 DISABLE QUERY REWRITE.

2,物化视图日志:如果需要进行快速刷新,则需要建立物化视图日志。物化视图日志根据不同物化祖峰的快速刷新的需要,可以建立为 ROWID 或 PRIMARY KEY 类型的

3,刷新(Refresh):指当基表发生了 DML 操作后,物化视图何时采用哪种方式和基表进行同步。刷新的模式有两种:ON DEMAND 和 ON COMMIT。

3-1,ON DEMAND 指物化视图在用户需要的时候进行刷新,可以手工通过 DBMS_MVIEW.REFRESH 等方法来进行刷新,也可以通过 JOB 定时进行刷新。

3-2,ON COMMIT 指物化视图在对藏青的 DML 操作提交的同时进行刷新。刷新的方法有四种:FAST、COMPLETE、FORCE、NEVER。

3-2-1,FAST 刷新采用增量刷新,只刷新自上次刷以后进行的修改。

3-2-2,COMPLETE 刷新是对整个物化视图进行完全的刷新。

3-2-3,如果选择 FORCE 方式,则 Oracle 在刷新时会去判断是否可以进行快速刷新,如果可以则采用 FAST 方式,否则采用 COMPLETE 的方式。

3-2-4,NEVER 指物化视图不进行任何刷新。默认值是 FORCE ON DEMAND。

四、掌握 11g 物化视图的建立和使用方法

1,创建时的权限

1-1,如果创建基于主键的物化视图,则必须具有访问主表、访问主表的日志、create MATERIALIZED VIEW 这三个权限

1-2,如果创建基于 rowid 的物化视图,则必须具有访问主表、create MATERIALIZED VIEW 这两个权限。

2,基于主键的物化视图

2-1,使用条件:远程表必须包含主键。

2-2,远端操作:创建主键表,并创建基于主表的视图日志

2-3,本地操作:创建一个过程,实现刷新本地物化视图的动作;创建一个 JOB,进行调用过程的操作;运行这个 JOB,则本地数据会与远程数据自动同步刷新一次

3,实际使用;例:

3-1,远端数据库:

create table stu(id varchar2(10) primary key, name varchar2(10));  --创建一张表

create materialized view log on stu; --创建物化视图日志

grant select on stu to hr;  --将查询 stu 表的权限赋给 hr 用户

system 用户赋权:grant create materialized view to hr:  --将创建物化视图的权限赋给 hr;

注意:如果表有主键,必须赋权:grant select on MLOG$_STU to hr;  --将访问物化视图日志的权限赋给 hr ;

说明:如果此时删除 stu 表,物化视图会自动删除

3-2,本地数据库:

create materialized view stu_view refresh  --创建一个物化视图

fast start  --刷新方式为 fast

with sysdate  --刷新开始时间为现在

next sysdate+1/1440  --下一次刷新时间为一分钟后

with primary key  --物化视图基于的表是有主键的

as 

select * from scott.stu;  --视图的内容

删除物化视图:drop materialized view stu_view;

4,实际使用;例:

4-1,远端数据库:

create table stu(id varchar2(10) primary key, name varchar2(10));  --创建一张表

create materialized view log on stu; --创建物化视图日志

grant select on stu to hr;  --将查询 stu 表的权限赋给 hr 用户

system 用户赋权:grant create materialized view to hr:  --将创建物化视图的权限赋给 hr;

注意:如果表有主键,必须赋权:grant select on MLOG$_STU to hr;  --将访问物化视图日志的权限赋给 hr ;

4-2,本地数据库:

create materialized view stu_view refresh  --创建一个物化视图

as 

select * from scott.stu;  --视图的内容

create or replace procedure test as  --创建一个过程刷新物化视图

begin

dbmw_mview.refresh('STU_VIEW');

end;

variable job1 number;  --写一程序来执行上面的过程

begin

dbms_job.submit(:job1,'test;',sysdate,'sysdate+1/1440');

end;

begin  --执行程序 

dbms_job.run(:job1);

end;

5,基于 rowid 的物化视图

5-1,使用条件:远程表可以没有主键

5-2,远端操作:创建表

5-3,本地操作:创建一个过程,实现刷新本地物化视图的动作:创建一个 JOB,进行调用过程的操作;运行这个 JOB,则本地数据会与远程数据自动刷新一次

6,实际使用;例:

6-1,远端数据库:

create table stu(id varchar2(10), name varchar2(10));  --创建一张表

grant select on stu to hr;  --将查询 stu 表的权限赋给 hr 用户

system 用户赋权:grant create materialized view to hr:  --将创建物化视图的权限赋给 hr;

6-2,本地数据库:

create materialized view stu_view refresh  with rowid --创建一个物化视图,没有主键的表创建物化视图时必须指明刷新依据为 rowid;

as 
select * from scott.stu;  --视图的内容
create or replace procedure test as  --创建一个过程刷新物化视图
begin
dbmw_mview.refresh('STU_VIEW');
end;
variable job1 number;  --写一程序来执行上面的过程
begin
dbms_job.submit(:job1,'test;',sysdate,'sysdate+1/1440');
end;
begin  --执行程序 
dbms_job.run(:job1);
end;