循序渐进Materialized ViewsWord格式.docx
《循序渐进Materialized ViewsWord格式.docx》由会员分享,可在线阅读,更多相关《循序渐进Materialized ViewsWord格式.docx(33页珍藏版)》请在冰豆网上搜索。
![循序渐进Materialized ViewsWord格式.docx](https://file1.bdocx.com/fileroot1/2023-1/29/56963070-753e-4495-bd36-0944f4cf089e/56963070-753e-4495-bd36-0944f4cf089e1.gif)
table
t
(a
int,
b
varchar2(50),
constraint
pk_tprimary
key(a));
Table
created.
--创建对应的MV名为MVT
materialized
view
mvt
as
select
*
from
t;
Materialized
--现在往表里面插入一些个数据
insert
into
rownum,
object_name
fromall_objects;
11449
rows
commit;
Commit
complete.
--现在我们看一下数据的情况
count(*)
COUNT(*)
----------
11449
--mvt还是没有数据的
mvt;
0
--下面对mview做一次刷新看看
exec
dbms_mview.refresh('
mvt'
);
-在pl/sql中的command窗口執行
PL/SQL
procedure
successfully
completed.
--现在能看到mv里面已经有数据了
--然后我们在看一下表T和MVT的结构可以发现他们两个是一样的
desc
Name
Null?
Type
-----------------------------------------
A
NOT
NULL
NUMBER(38)
B
VARCHAR2(50)
从上面的例子可以看到我们利用MV创建了一个现有数据表的一个复制,同时通过刷新的方式将两个数据表的数据进行了同步。
这个就是我们在复制中利用MView的最主要的用法,所不同的是在实际应用的环境中表T和MViewMVT并不是在同一个机器上,而是分散在两个以上的机器上,同时基表也可能不止一个,可能存在多个。
下面列举了MView在实际中的主要作用:
∙减轻网络负担:
通过MV将数据从一个数据库分发到多个不同的数据库上,通过对多个数据库访问来减轻对单个数据库的网络负担。
∙搭建分发环境:
通过从一个中央数据库将数据分发到多个节点数据库,达到分发数据的目的。
∙复制数据子集:
MV可以进行行级/列级的筛选,这样可以复制需要的那一部分数据。
∙支持离线计算:
MV不需要专用的数据库连接,用户可以按照自己的需求来复制所需要的那一部分数据。
下面接着说说MView刷新这个事。
MView里面的数据是不会和基表保持实时的同步的,它只是基表在某时时间点(刷新的时间点)的一个一致性的数据的镜像,因此,要保持MView尽可能的和基表同步的话就需要我们定期的对MView进行刷新。
Oracle支持三种种方式的刷新:
完全刷新和快速刷新以及强制刷新。
完全刷新(completerefresh)
对一个MView进行全部刷新的时候差不多是将MView重建了,在进行MView全部刷新的时候会现将MView中现有的数据删除(版本在10G或以上)或者TRUNCATE(版本低于9i),然后在根据创建MView时候的查询生成数据插入到MView中。
对于多层的MView来说,当masterMView全部刷新之后对应的下一级的MView也需要全部刷新,否则将会收到ORA-12034的错误。
快速刷新(fastrefresh)
快速刷新是一种比完全刷新快的多的刷新方式,快速刷新只刷新自上次刷新以来修改的数据,因为快速刷新所要操作的数据量少,使用这种方法能大大的节省带宽.
快速刷新要求在基表上面有MViewLog,接着上面给出的例子,我们来给MVT做一个快速刷新。
--现在表T上面创建MViewLog
--如果没有建立MViewLog的话要进行快速刷新的话会报错的,大家可以试试
log
on
--先看一下我们要修改的数据
where
a=936;
B
------------------------------------------------------------
936
v_$fast_start_servers
--接着对表T数据进行一些修改
update
set
b=upper(b)
1
row
updated.
--现在T里面的这条数据变成了这样
V_$FAST_START_SERVERS
--接下来就是进行快速刷新了
'
F'
--现在看MVT里面的结果
快速刷新最大的问题在于如果保证能进行快速刷新,这是对与复杂的查询来说是有些挑战的问题,以后会慢慢的探讨。
强制刷新(forcerefresh)
当进行强制刷新的时候系统会首先尝试进行快速刷新,如果快速刷新无法进行的时候系统将会进行完全刷新。
其实就是一个快速刷新和完全刷新的结合体。
既然有那么多种的刷新方式那我们怎么指定他们呢?
在Oracle中有两种方法来制定所用的刷新方式,第一种在上面我们已经看过了,就是在执行刷新MView语句的时候制定刷新方式,比如说
用来指定对MViewmvt进行快速刷新,将其中的”F”改成”C”就是指定对mvt进行完全刷新了。
C'
另外一种方法是直接执行
就是不指定刷新的参数,这个时候MView的刷新方式将是根据创建时候由REFRESH语句指定的刷新方法来进行刷新了,REFRESH语句一共有下面几种使用方法
[refresh
[fast
|
complete
force]
......
]
∙FAST:
采用增量刷新,只刷新自上次刷新以后进行的修改
∙COMPLETE:
对整个实体化视图进行完全的刷新
∙FORCE(默认):
Oracle在刷新时会去判断是否可以进行快速刷新,如果可以则采用Fast方式,否则采用Complete的方式,Force选项是默认选项
现在怎么刷新的问题解决了,接下来就是考虑我们什么时候进行刷新了。
我们从上面已经知道我们需要定期的对MView进行刷新以保证基表和MView的数据同步,这个定期的方法就是使用job,同样我们有两种方法来创建刷新MView的job。
使用DBMS_JOB包来创建
--提交一个JOB用来刷新MView
variable
job1
number;
execdbms_job.submit(:
job1,'
"
user"
."
mvt"
sysdate,'
sysdate+1/24'
--查看一下结果
JOB,NEXT_DATE,NEXT_SEC,INTERVAL,WHAT
fromuser_jobs;
JOB
NEXT_DATE
NEXT_SEC
INTERVAL
WHAT
---------------------------------------------------------------------------------------------------------------------------
23
2009-01-13
13:
52:
14
sysdate+1/24
使用这种方法相对下面的方法来说不同之处在于这种方法可以自己指定刷新的语句,这样灵活性相对高一些。
在创建MView的时候指定REFRESH语句
没错,还是REFRESH语句,这个语句的用法还是挺多的,下面列出这个语句的其他用法:
......
[start
with
date]
[next
∙STARTWITH:
第一次刷新时间
∙NEXT:
刷新时间间隔
说明:
指定上面两个选项的任意一个都将会在系统中产生一个新的JOB,用来对所建立的MV进行刷新,这个JOB可以从DBA_JOBS查到,同时删除MV之后该JOB也会被删除。
下面我们看一个例子:
--创建一个MView,并指定刷新时间为sysdate和刷新间隔为一个小时
mvt2
refresh
start
sysdatenext
--现在我们看一下job
--请注意这里的WHAT那一栏中MView刷新的代码是不带刷新方式的,也就是说按照创建时候的刷新方式进行刷新
------------------------------------------------------------------------------------
21
20:
20
dbms_refresh.refresh('
USER"
MVT2"
另外这里所说的JOB定时刷新只是针对于单个MView来说的,而对于存在多个MView要刷新的时候我们就要开始考虑刷新组了,这个部分以后再慢慢说明。
说了这么多的MView的例子,那么MView的结构到底是怎么样的呢?
我们先看一副Oracle给出的MView的结构图:
MView架构图(来自OracleAdvanceReplication)
现在我们只对一些当前接触到的相关的对象进行说明,其他的部分将在后面的文章中陆续说明:
必要组成部分
∙基表(MASTERTABLE):
这里说的基表不一定只有一个表,也有可能是一个复杂的查询,涉及很多的表,也可能是一个MView。
∙隐藏的MView对象:
对象类型为MaterializedView的一个对象,用来维护MView的创建信息。
∙MView表:
MView所对应的数据表,这个表也就是一个普通的表,不同的就是这个表是和一个MView相关联的表。
∙基表的INDEX
∙MView的INDEX:
对以用PK建立的MView将会有一个与基表结果一样名字类似的索引,对以使用ROWID建立的MView将有一个以I_SNAP$_materialized_view_name格式命名的建立在ROWID列上的INDEX。
当然你也可以根据需要自己再创建一些INDEX。
对于需要快速刷新的物化视图
∙MViewLOG:
要使MView能够被快速刷新的话必须在基表上面创建MViewLog,创建MViewLog的语法为CREATEMATERIALIZEDVIEWLOGONmaster_name,MViewLog表为Oracle默认以MLOG$_master_name的命名格式建立。
∙维护MLOG$_的内部触发器:
在基表上面的所有DML操作都有一个在基表上的内部触发器记录到MLOG$_master_name中,这个触发器在USER_TRIGGERS是看不到的,不过能够用USER_INTERNAL_TRIGGERS看到。
下面用一个例子来看一下这些个对象
--创建一个基表
SQL>
CREATE
TABLE
TTT1(A
INT
PRIMARY
KEY,
INT);
--以TTT1为基表创建一个可更新的MView
SNAPSHOT
MV_TTT1
FOR
UPDATE
AS
SELECT
FROM
TTT1;
--创建MViewLog
MATERIALIZED
VIEW
LOG
ON
--检查MView的对象
OBJECT_NAME,
OBJECT_TYPE
ALL_OBJECTS
WHEREOBJECT_NAME
LIKE
%TTT1%'
;
OBJECT_NAME
OBJECT_TYPE
-------------------------------------------------
TTT1
TABLE
VIEW
MLOG$_TTT1
USLOG$_MV_TTT1
--查看MView相关的INDEX
INDEX_NAME,TABLE_NAME
USER_INDEXES
WHERE
TABLE_NAMELIKE
INDEX_NAME
TABLE_NAME
------------------------------------------------------------
PK_TTT11
MV_TTT1
PK_TTT1
TTT1
--查看内部触发器
USER_INTERNAL_TRIGGERS
TABLE_NAME
LIKE'
INTERNAL_TRIGGER_TY
UPDATABLE
MVIEW
LOG
循序渐进MView
(二)MViewLog的结构与快速刷新
马齿苋发表评论阅读评论985次查看
MViewLog的结构
刷新的过程
完全刷新的过程
快速刷新过程
参考资料
现在我们通过一些例子来说明一下MViewLog的基本结构以及MView快速刷新的过程。
在这一部分里面,我们还是利用上一部分提供的例子先建立一个MView,同时也创建该MView基表的MViewLog。
我们先看一下两个测试表的MViewLog的结构:
--含有PK的MView
mlog$_t;
------------------------------------------
NUMBER
SNAPTIME$$
DATE
DMLTYPE$$
VARCHAR2
(1)
OLD_NEW$$
CHANGE_VECTOR$$
RAW(255)
现在我们挨个说一下各列的含义:
A
这个我们基表T的主键列,如果基表的主键是一个复合索引的话那这里也