测试mv刷新组是否可以同时刷新组内物化视图

Posted fooobabar

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了测试mv刷新组是否可以同时刷新组内物化视图相关的知识,希望对你有一定的参考价值。

我们知道刷新组的目的是为了解决外键关系表刷新先后的问题,从这个目的出发,说明刷新组内物化视图刷新是串行的。
我通过触发器的方式,监控了一下这个现象。 同时也说明了刷新组内,物化视图的刷新并不能并行。

 

--创建物化视图日志 
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; 


--创建测试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; 

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


--创建触发器监控表 

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;
/


---原表更新数据 
--生成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;  



--启动刷新组

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

  

这个触发器记录的时间就有意思了, 说明是mv_agent先刷新的,然后才刷新mv_policy

以上是关于测试mv刷新组是否可以同时刷新组内物化视图的主要内容,如果未能解决你的问题,请参考以下文章

物化视图上的快速刷新给出错误

PostgreSQL物化视图刷新“堆叠”

物化视图在NEEDS_COMPILE状态下刷新

是否可以在 PostgreSQL 中部分刷新物化视图?

Oracle - 物化视图中的视图

刷新物化视图时,索引是不是也会自动刷新?