test,测试物化视图刷新组是否并行刷新
我们知道刷新组的目的是__为了解决外键关系表刷新先后的问题__,从这个目的出发,推断刷新组内物化视图刷新是串行的。
我通过触发器的方式,监控了一下这个现象。 同时也说明了刷新组内,物化视图并不是并行刷。
结论:物化视图刷新组并不是并行刷新的
- 数据库版本 Oracle 11.2.0.4
1. 创建物化视图原表
--原表
CREATE TABLE POLICY (ID INTEGER PRIMARY KEY , PRODUCT_NAME VARCHAR2(200));
CREATE TABLE AGENT (agent_code VARCHAR2(30) PRIMARY KEY , NAME VARCHAR2(200));
--物化视图日志
CREATE MATERIALIZED VIEW LOG ON policy WITH PRIMARY KEY;
CREATE MATERIALIZED VIEW LOG ON AGENT WITH PRIMARY KEY;
2. 创建物化视图
--创建测试mv
CREATE MATERIALIZED VIEW mv_policy
REFRESH FAST ON DEMAND
NEXT NULL
AS
select * from policy ;
CREATE MATERIALIZED VIEW mv_agent
REFRESH FAST ON DEMAND
NEXT NULL
AS
select * from AGENT;
3. 把物化视图合并到一个刷新组
SELECT * FROM user_jobs;
--查看物化视图默认在哪个刷新组
select * from user_refresh_children where NAME = 'MV_POLICY';
select * from user_refresh_children where NAME = 'MV_AGENT';
SQL> select NAME,RNAME from user_refresh_children where NAME = 'MV_POLICY';
NAME RNAME
------------------------------------------------------------ ------------------------------------------------------------
MV_POLICY MV_POLICY
SQL> select NAME,RNAME from user_refresh_children where NAME = 'MV_AGENT';
NAME RNAME
------------------------------------------------------------ ------------------------------------------------------------
MV_AGENT MV_AGENT
--查看有几个刷新组
SQL> select ROWNER, RNAME, REFGROUP from user_refresh;
ROWNER RNAME REFGROUP
------------------------------------------------------------ ------------------------------------------------------------ ----------
SCOTT MV_EMP 1
SCOTT MV_POLICY 2
SCOTT MV_AGENT 3
--mv从刷新组里去掉之后,如果刷新组没有mv,则刷新组也消失了。
BEGIN
dbms_refresh.subtract(name => 'MV_POLICY',list => 'MV_POLICY');
commit;
END;
BEGIN
dbms_refresh.subtract(name => 'MV_AGENT',list => 'MV_AGENT');
commit;
END;
再看看,就只剩下mv_emp了 ,这个物化视图不是这次测试要用到的。
SQL> select ROWNER, RNAME, REFGROUP from user_refresh;
ROWNER RNAME REFGROUP
------------------------------------------------------------ ------------------------------------------------------------ ----------
SCOTT MV_EMP 1
--创建刷新组,创建刷新组时可以不指定组内的MV,但是next_date和 interval 需要指定,可以为空。
BEGIN
dbms_refresh.make(name => 'refgroup01',list => '',next_date => NULL,interval => NULL);
commit;
END;
SQL> select ROWNER, RNAME, REFGROUP from user_refresh;
ROWNER RNAME REFGROUP
------------------------------------------------------------ ------------------------------------------------------------ ----------
SCOTT MV_EMP 1
SCOTT REFGROUP01 4
--给刷新组增加MV
BEGIN
dbms_refresh.add(name => 'REFGROUP01',list => 'mv_policy,mv_agent');
commit;
END;
SQL> select NAME,RNAME from user_refresh_children where rname='REFGROUP01';
NAME RNAME
------------------------------------------------------------ ------------------------------------------------------------
MV_POLICY REFGROUP01
MV_AGENT REFGROUP01
4. 新增触发器
--创建触发器监控表
create table BUSINESS_LOG_2
(
datecode DATE not null,
tablename VARCHAR2(40) not null,
businessfield1 VARCHAR2(20) not null,
field1_content VARCHAR2(300) not null,
businessfield2 VARCHAR2(20),
field2_content VARCHAR2(600),
businessfield3 VARCHAR2(20),
field3_content VARCHAR2(300),
businessfield4 VARCHAR2(20),
field4_content VARCHAR2(300),
businessfield5 VARCHAR2(20),
field5_content VARCHAR2(300),
businessfield6 VARCHAR2(20),
field6_content VARCHAR2(300),
businessfield7 VARCHAR2(20),
field7_content VARCHAR2(600),
businessfield8 VARCHAR2(20),
field8_content VARCHAR2(300),
businesstype VARCHAR2(10) not null,
sourceflag CHAR(1),
remark VARCHAR2(20),
businessfield9 VARCHAR2(20),
field9_content VARCHAR2(300)
);
CREATE OR REPLACE TRIGGER tri_mv_policy
before update or insert on mv_policy for each row
begin
--update操作记录
insert into Business_Log_2
(BusinessType,
DateCode,
TableName,
BusinessField1,
Field1_Content,
SourceFlag,
Remark)
values
('OLD',
sysdate,
'MV_POLICY',
'ID',
nvl(:OLD.ID, 1),
'1',
NULL);
--insert操作记录
insert into Business_Log_2
(BusinessType,
DateCode,
TableName,
BusinessField1,
Field1_Content,
SourceFlag,
Remark)
values
('NEW',
sysdate,
'MV_POLICY',
'ID',
nvl(:new.ID, 1),
'1',
NULL);
end;
/
CREATE OR REPLACE TRIGGER tri_mv_agent
before update or insert on mv_agent for each row
begin
--update操作记录
insert into Business_Log_2
(BusinessType,
DateCode,
TableName,
BusinessField1,
Field1_Content,
SourceFlag,
Remark)
values
('OLD',
sysdate,
'MV_AGENT',
'AGENT_CODE',
nvl(:OLD.AGENT_CODE, 1),
'1',
NULL);
--insert操作记录
insert into Business_Log_2
(BusinessType,
DateCode,
TableName,
BusinessField1,
Field1_Content,
SourceFlag,
Remark)
values
('NEW',
sysdate,
'MV_AGENT',
'AGENT_CODE',
nvl(:new.AGENT_CODE, 1),
'1',
NULL);
end;
/
5. 更新原表数据,产生增量
---原表更新数据
--生成mvlog
INSERT INTO policy (id, product_name)
SELECT level, ora_hash(LEVEL) FROM dual CONNECT BY LEVEL <= 99999;
COMMIT;
INSERT INTO AGENT (agent_code, name)
SELECT level, ora_hash(LEVEL) FROM dual CONNECT BY LEVEL <= 88888;
COMMIT;
6. 刷新物化视图观察结果
--启动刷新组
BEGIN
dbms_refresh.refresh(name => 'REFGROUP01');
commit;
END;
SQL> alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss";
Session altered.
SQL> select TABLENAME,MIN(datecode),MAX(datecode) from business_log_2 group by TABLENAME ;
TABLENAME MIN(DATECODE) MAX(DATECODE)
-------------------------------------------------------------------------------- ------------------- -------------------
MV_AGENT 2020-04-09 23:35:46 2020-04-09 23:36:00
MV_POLICY 2020-04-09 23:36:00 2020-04-09 23:36:15