物化视图

来源:互联网 发布:网络维护工程师 编辑:程序博客网 时间:2024/06/16 18:37

http://www.cnblogs.com/linjiqin/archive/2012/05/23/2514795.html  物化视图日志结构
http://blog.itpub.net/4227/viewspace-260459/  物化视图的维护
http://www.cnblogs.com/suredandan/p/3927118.html   共用物化视图日志。

http://blog.csdn.net/tianlesoftware/article/details/4713553    Oracle 物化视图 说明  
http://blog.csdn.net/tianlesoftware/article/details/7720580  Oracle 物化视图日志 与 快速刷新 说明 

oracle物化视图日志结构

     物化视图的快速刷新要求基本必须建立物化视图日志,这篇文章简单描述一下物化视图日志中各个字段的含义和用途。

     物化视图日志的名称为MLOG$_后面跟基表的名称,如果表名的长度超过20位,则只取前20位,当截短后出现名称重复时,Oracle会自动在物化视图日志名称后面加上数字作为序号。

      物化视图日志在建立时有多种选项:可以指定为ROWIDPRIMARY KEYOBJECT ID几种类型,同时还可以指定SEQUENCE或明确指定列名。上面这些情况产生的物化视图日志的结构都不相同。

                 

任何物化视图都会包括的4列:
SNAPTIME$$
:用于表示刷新时间。
DMLTYPE$$
:用于表示DML操作类型,I表示INSERTD表示DELETEU表示UPDATE
OLD_NEW$$
:用于表示这个值是新值还是旧值。NEW)表示新值,OLD)表示旧值,U表示UPDATE操作。
CHANGE_VECTOR$$
:表示修改矢量,用来表示被修改的是哪个或哪几个字段。
如果WITH后面跟了ROWID,则物化视图日志中会包含:M_ROW$$:用来存储发生变化的记录的ROWID
如果WITH后面跟了PRIMARY KEY,则物化视图日志中会包含主键列。
如果WITH后面跟了OBJECT ID,则物化视图日志中会包含:SYS_NC_OID$:用来记录每个变化对象的对象ID
如果WITH后面跟了SEQUENCE,则物化视图日子中会包含:SEQUENCE$$:给每个操作一个SEQUENCE号,从而保证刷新时按照顺序进行刷新。
如果WITH后面跟了一个或多个COLUMN名称,则物化视图日志中会包含这些列。

           

下面通过例子进行详细说明:

SQL> create table t_rowid (id number, namevarchar2(30), num number);
表已创建。

            
SQL> create materialized view log on t_rowid with rowid, sequence (name,num) including new values;
实体化视图日志已创建。

               
SQL> create table t_pk (id number primary key, name varchar2(30), numnumber);
表已创建。

               
SQL> create materialized view log on t_pk with primary key;
实体化视图日志已创建。

            
SQL> create type t_object as object (id number, name varchar2(30), numnumber);
     /
类型已创建
                

SQL> create table t_oid of t_object;
表已创建。

             
SQL> desc t_oid;
名称                                     是否为空?类型
----------------------------------------- -------- ---------------
ID                                                NUMBER
NAME                                              VARCHAR2(30)
NUM                                               NUMBER

               
SQL> create materialized view log on t_oid with object id;
实体化视图日志已创建。

        

建立环境后来看看物化视图日志中包含的字段:
SQL> desc mlog$_t_rowid;
名称                                     是否为空?类型
----------------------------------------- -------- -------------
NAME                                              VARCHAR2(30)
NUM                                               NUMBER
M_ROW$$                                           VARCHAR2(255)
SEQUENCE$$                                        NUMBER
SNAPTIME$$                                        DATE
DMLTYPE$$                                         VARCHAR2(1)
OLD_NEW$$                                         VARCHAR2(1)
CHANGE_VECTOR$$                                   RAW(255)
除了最基本的4列之外,由于指定了ROWIDSEQUENCENAMENUM列,因此物化视图日志中包含了相对应的列。

                 
SQL> desc mlog$_t_pk;
名称                                     是否为空?类型
----------------------------------------- -------- ------------
ID                                                NUMBER
SNAPTIME$$                                        DATE
DMLTYPE$$                                         VARCHAR2(1)
OLD_NEW$$                                         VARCHAR2(1)
CHANGE_VECTOR$$                                   RAW(255)

           
对象表的物化视图日志建立后包含系统对象标识列。
一、主键列、ROWID列、OBJECT ID列、SEQUENCE列和建立物化视图时指明的列。
主键、ROWIDOBJECT ID用来唯一表示物化视图日志中的记录。
SEQUENCE
会根据操作发生的顺序对物化视图日志中的记录编号。

         
建立物化视图时指明的列会在物化视图日志中进行记录。  

SQL> insert into t_pk values (1, 'a', 5);
已创建 1行。

           
SQL> update t_pk set name = 'c' where id = 1;
已更新 1行。

         
SQL> delete t_pk;
已删除 1行。

            
SQL> select id, dmltype$$ from mlog$_t_pk;
        ID D
---------- -
         1 I
         1 U
         1 D

          
SQL> insert into t_oid values (1, 'a', 5);
已创建 1行。

         
SQL> update t_oid set name = 'c' where id = 1;
已更新 1行。

          
SQL> delete t_oid;
已删除 1行。

             
SQL> select sys_nc_oid$, dmltype$$ from mlog$_t_oid;
SYS_NC_OID$                     D
-------------------------------- -
18DCFDE5D65B4D5A88602D6C09E5CE20 I
18DCFDE5D65B4D5A88602D6C09E5CE20 U
18DCFDE5D65B4D5A88602D6C09E5CE20 D

            
SQL> rollback;

回退已完成。

   

二、时间列
     
当基本发生DML操作时,会记录到物化视图日志中,这时指定的时间400011000秒。如果物化视图日志供多个物化视图使用,则一个物化视图刷新后会将它刷新的记录的时间更新为它刷新的时间。
     
下面建立快速刷新的两个物化视图来演示时间列的变化。(只有建立快速刷新的物化视图才能使用物化视图日志,如果只建立一个物化视图,则物化视图刷新完会将物化视图日志清除掉。

            

SQL> create materialized view mv_t_rowid refreshfast on commit as select name, count(*) from t_rowid group by name;
实体化视图已创建。

            
SQL> create materialized view mv_t_rowid1 refresh fast as select name,count(*) from t_rowid group by name;
实体化视图已创建。

             
SQL> insert into t_rowid values (1, 'a', 5);
已创建 1行。

              
SQL> update t_rowid set name = 'c' where id = 1;
已更新 1行。

              
SQL> delete t_rowid;
已删除 1行。

          
SQL> select snaptime$$ from mlog$_t_rowid;
SNAPTIME$$
-------------------
4000-01-01 00:00:00
4000-01-01 00:00:00
4000-01-01 00:00:00
4000-01-01 00:00:00

            
SQL> commit;
提交完成。

          
SQL> select snaptime$$ from mlog$_t_rowid;
SNAPTIME$$
-------------------
2012/5/23 15:41:41
2012/5/23 15:41:41
2012/5/23 15:41:41
2012/5/23 15:41:41
COMMIT
后,物化视图mv_t_rowid刷新,将SNAPTIME$$列更新成自己的刷新时间。

      

三、操作类型和新旧值
操作类型比较简单:只包括I(INSERT)D(DELETE)U(UPDATE)三种。
新旧值也包括三种:O表示旧值(一般对应的操作时DELETE)、N表示新值(一般对应的操作是INSERT),还有一种U(对应UPDATE操作)。

SQL> insert into t_pk values (1, 'a', 5);
已创建 1行。
      
SQL> insert into t_pk values (2, 'b', 7);
已创建 1行。
         
SQL> insert into t_pk values (3, 'c', 9);
已创建 1行。
            
SQL> update t_pk set name = 'c' where id = 1;
已更新 1行。
           
SQL> update t_pk set id = 4 where id = 2;
已更新 1行。
       
SQL> delete t_pk where id = 3;
已删除 1行。
           
SQL> select id, dmltype$$, old_new$$ from mlog$_t_pk;
        ID D O
---------- - -
         1 I N
         2 I N
         3 I N
         1 U U
         2 D O
         4 I N
         3 D O
已选择7行。
        
开始是插入三条记录,接着是UPDATE操作。需要注意,对于基于主键的物化视图日志,如果更新了主键,则UPDATE操作转化为一条DELETE操作,一条INSERT操作。最后是DELETE操作。

SQL> drop materialized view log on t_rowid;
实体化视图日志已删除。
        
SQL> create materialized view log on t_rowid with rowid, sequence (name,num) including new values;
实体化视图日志已创建。
          
SQL> insert into t_rowid values (1, 'a', 5);
已创建 1行。
         
SQL> insert into t_rowid values (2, 'b', 7);
已创建 1行。
        
SQL> insert into t_rowid values (3, 'c', 9);
已创建 1行。
        
SQL> update t_rowid set name = 'c' where id = 1;
已更新 1行。
       
SQL> update t_rowid set id = 4 where id = 2;
已更新 1行。
       
SQL> delete t_rowid where id = 3;
已删除 1行。
           
SQL> select name, num, m_row$$, dmltype$$, old_new$$ from mlog$_t_rowid;
NAME             NUM M_ROW$$           D   O
---------- ---------- ------------------ - -
a                  5 AAACIDAAFAAAAD4AAC I N
b                  7 AAACIDAAFAAAAD4AAA I N
c                  9 AAACIDAAFAAAAD4AAB I N
a                  5 AAACIDAAFAAAAD4AAC U U
c                  5 AAACIDAAFAAAAD4AAC U N
b                  7 AAACIDAAFAAAAD4AAA U U
b                  7 AAACIDAAFAAAAD4AAA U N
c                  9 AAACIDAAFAAAAD4AAB D O

已选择8行。

查询结果和上面类似,唯一的区别是每条UPDATE操作都对应物化视图日志中的两条记录。一条对应UPDATE操作的原记录DMLTYPE$$OLD_NEW$$都为U,一条对应UPDATE操作后的新记录,DMLTYPE$$UOLD_NEW$$N。当建立物化视图日志时指出了INCLUDING NEW VALUES语句时,就会出现这种情况。

     

四、修改矢量
     
最后简单讨论一下CHANGE_VECTOR$$列。
      INSERT
DELETE操作都是记录集的,即INSERTDELETE会影响整条记录。而UPDATE操作是字段集的,UPDATE操作可能会更新整条记录的所有字段,也可能只更新个别字段。
     
无论从性能上考虑还是从数据的一致性上考虑,物化视图刷新时都应该是基于字段集。Oracle就是通过CHANGE_VECTOR$$列来记录每条记录发生变化的字段包括哪些。

     基于主键、ROWIDOBJECT ID的物化视图日志在CHANGE_VECTOR$$上略有不同,但是总体设计的思路是一致的。     

      CHANGE_VECTOR$$列是RAW类型,其实Oracle采用的方式就是用每个BIT位去映射一个列。

     比如:第一列被更新设置为02,即00000010。第二列设置为04,即00000100,第三列设置为08,即00001000。当第一列和第二列同时被更新,则设置为0600000110。如果三列都被更新,设置为0E00001110
     
依此类推,第4列被更新时为10,第520,第640,第780,第80001。当第1000列被更新时,CHANGE_VECTOR$$的长度为1000/4+2252
     
除了可以表示UPDATE的字段,还可以表示INSERTDELETEDELETE操作CHANGE_VECTOR$$列为全0,具体个数由基表的列数决定。INSERT操作的最低位为FE如果基表列数较多,而存在高位的话,所有的高位都为FF。如果INSERT操作是前面讨论过的由UPDATE操作更新了主键造成的,则这个INSERT操作对应的CHANGE_VECTOR$$列为全FF

         

SQL> insert into t_rowid values (1, 'a', 5);
已创建 1行。
    
SQL> insert into t_rowid values (2, 'b', 7);
已创建 1行。
           
SQL> insert into t_rowid values (3, 'c', 9);
已创建 1行。
         
SQL> update t_rowid set name = 'c' where id = 1;
已更新 1行。
         
SQL> update t_rowid set id = 4 where id = 2;
已更新 1行。
         
SQL> update t_rowid set name = 'd', num = 11 where id = 3;
已更新 1行。
        
SQL> delete t_rowid where id = 3;
已删除 1行。
 
SQL> select name, num, m_row$$, dmltype$$, old_new$$, change_vector$$ frommlog$_t_rowid;
 说明: http://pic002.cnblogs.com/images/2012/270324/2012052316184092.png
可以看到,正如上面分析的,INSERTFEDELETE00,对第一列的更新为02,第二列为04,第二列和第三列都更新为0C。需要注意,正常情况下,第一列会从02开始,但是如果对MLOG$表执行了TRUNCATE操作,或者重建了物化视图日志,则可能造成第一列开始位置发生偏移。

SQL> insert into t_pk values (1, 'a', 5);
已创建 1行。
        
SQL> insert into t_pk values (2, 'b', 7);
已创建 1行。
        
SQL> insert into t_pk values (3, 'c', 9);
已创建 1行。
          
SQL> update t_pk set name = 'c' where id = 1;
已更新 1行。
          
SQL> update t_pk set id = 4 where id = 2;
已更新 1行。
       
SQL> delete t_pk where id = 1;
已删除 1行。
        
SQL> commit
提交完成。
     
SQL> select * from mlog$_t_pk;

说明: http://pic002.cnblogs.com/images/2012/270324/2012052316213625.png

这个结果和ROWID类型基本一致,不同的是,如果更新了主键,会将UPDATE操作在物化视图日志中记录为一条DELETE和一条INSERT,不过这时INSERT对应的CHANGE_VECTOR$$的值是FF

 SQL> insert into t_oid values (1, 'a', 5);
已创建 1行。
       
SQL> update t_oid set name = 'c' where id = 1;
已更新 1行。
       
SQL> update t_oid set id = 5 where id = 1;
已更新 1行。
       
SQL> delete t_oid;
已删除 1行。
      
SQL> commit;
提交完成。
         
SQL> select * from mlog$_t_oid;

说明: http://pic002.cnblogs.com/images/2012/270324/2012052316303010.png

SQL> select name, segcollength from sys.col$where obj# = (select object_id from user_objects where object_name ='T_OID');

NAME                          SEGCOLLENGTH
------------------------------ ------------
SYS_NC_OID$                        16
SYS_NC_ROWINFO$                1
ID                                         22
NAME                                    30
NUM                                      22

这个结果也和ROWID类型基本一致,需要注意的是,由于对象表包含两个隐含列,因此ID不再是第一个字段,而是第三个,因此对应的值是08

SQL> create table t (
   col1 number,
   col2 number,
   col3 number,
   col4 number,
   col5 number,
   col6 number,
   col7 number,
   col8 number,
   col9 number,
   col10 number,
   col11 number,
   col12 number
);
表已创建。

SQL> create materialized view log on t withrowid;
实体化视图日志已创建。
        
SQL> insert into t values (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
已创建 1行。
          
SQL> update t set col1 = 10;
已更新 1行。
         
SQL> update t set col11 = 110;
已更新 1行。
        
SQL> update t set col5 = 50, col12 = 120;
已更新 1行。
        
SQL> delete t;
已删除 1行。
        
SQL> commit;
提交完成。
    
SQL> select * from mlog$_t;

说明: http://pic002.cnblogs.com/images/2012/270324/2012052316362156.png

最后看一个包含列数较多的例子,唯一需要注意的是,低位在左,高位在右。

 

 

 

 

 

物化视图日志的维护

物化视图日志经常会由于物化视图长时间没有刷新,或者基表的一次批量数据更改而变得很大,这会影响物化视图的刷新性能,因此对于这种情况需要对物化视图日志进行处理,降低物化视图日志表的高水位线。

 

 

Oracle的物化视图的快速刷新功能,主要是靠物化视图日志来实现的。

物化视图日志会记录下基表所有的增、删、改操作,而物化视图执行完快速刷新操作后,会从物化视图日志中将本物化视图刷新过且其他物化视图所不需要刷新的记录删除掉。如果其中一个物化视图一直不刷新,那么物化视图日志就会变得越来越大。

还有一种情况,比如表中插入了大量的数据,或者删除了大量的数据,或者将表中的某一列统一更新为一个值,这种操作都会在物化视图日志中产生大量的记录。

而物化视图日志的增大必然影响物化视图的刷新速度。一方面,物化视图在刷新的时候要扫描物化视图日志,另一方面,物化视图在刷新介绍后,也要清除物化视图日志中的记录,仍然要扫描物化视图日志,因此物化视图日志的大小直接会影响物化视图快速刷新的速度。更重要的是,物化视图日志的高水位一旦增长到一个很高的位置,即使以后物化视图日志中记录很少,甚至没有记录存在,物化视图在刷新的时候仍然需要较长的时间。

因此,在对于物化视图的基表进行操作时,应注意尽量更新需要更新的记录:

SQL> CREATE TABLE T (ID NUMBERPRIMARY KEY, NAME VARCHAR2(30));

表已创建。

SQL> INSERT INTO T SELECT ROWNUM,OBJECT_NAME FROM DBA_OBJECTS;

已创建50674行。

SQL> CREATE MATERIALIZED VIEW LOGON T;

实体化视图日志已创建。

用一个最简单的例子来说明什么叫做更新需要更新的记录。现在需要将T表中的NAME字段全部用大写来表示,最简单的写法:

SQL> UPDATE T SET NAME =UPPER(NAME);

已更新50674行。

SQL> SELECT COUNT(*) FROMMLOG$_T;

  COUNT(*)
----------
     50674

SQL> ROLLBACK;

回退已完成。

但是这种写法就会造成一些没有必要更新的记录也执行了更新操作,从而导致物化视图日志中记录了很多没有必要刷新的记录,这些记录不但影响物化视图日志的高水位线,而且会增加物化视图刷新的成本。

对于物化视图的基表,这个刷新则应该改写为:

SQL> UPDATE T SET NAME =UPPER(NAME) WHERE NAME != UPPER(NAME);

已更新34007行。

SQL> SELECT COUNT(*) FROMMLOG$_T;

  COUNT(*)
----------
     34007

采用这种方式就可以避免刷新不必要的列而使得物化视图日志变得很大。

不过有的时候大数据量的操作无可避免,或者物化视图日志本身已经变得很大,已经开始影响物化视图的刷新性能了,那么就只能通过维护物化视图日志表的方式来降低高水位线。

不应该对物化视图日志执行TRUNCATETABLE操作。因为即使查询物化视图日志表中不存在记录,也无法确保在执行TRUNCATE TABLE操作之前,没有其他会话修改物化视图基表,从而导致新的记录插入物化视图日志中。

一旦发生物化视图日志记录被TRUNCATE的情况,就会导致物化视图和物化视图基表的数据不一致。例如:

SQL> CREATE MATERIALIZED VIEWMV_T REFRESH FAST AS SELECT * FROM T;

实体化视图已创建。

SQL> INSERT INTO T VALUES (60000,'A');

已创建 1行。

SQL> TRUNCATE TABLE MLOG$_T;

表被截断。

SQL> INSERT INTO T VALUES (60001,'B');

已创建 1行。

SQL> EXECDBMS_MVIEW.REFRESH('MV_T')

PL/SQL 过程已成功完成。

SQL> SELECT * FROM MV_T WHERE ID>= 60000;

       ID NAME
---------- ------------------------------
     60001 B

即使采用LOCK表的方式配合TRUNCATE,也无法避免并发的问题。

尝试在TRUNCATE之前LOCK物化视图日志表,很可能在TRUNCATE操作的时候失败:

SQL> LOCK TABLE MLOG$_T INEXCLUSIVE MODE;

表已锁定。

会话1锁定物化视图日志表,这时会话2插入基表一条记录:

SQL> SET SQLP 'SQL2> '
SQL2> INSERT INTO T VALUES (60002, 'C');

会话1执行TRUNCATE语句:

SQL> TRUNCATE TABLE MLOG$_T;
TRUNCATE TABLE MLOG$_T
              *
1行出现错误:
ORA-00054:
资源正忙, 但指定以 NOWAIT 方式获取资源

会话2成功插入记录:


已创建 1行。

SQL2> SELECT ID FROM MLOG$_T;

       ID
----------
     60002

这是由于会话1执行TRUNCATE操作,会先发出一个COMMIT,从而释放了MLOG$_T上的锁,而这时会话2获得了MLOG$_T上的锁,并插入记录。由于会话2获得了物化视图日志上的锁,会话1尝试TRUNCATE就会失败。

如果尝试在基表上加锁,虽然可以避免基表的修改造成的物化视图日志改变,但是无法避免手工修改物化视图日志表的情况,虽然这种情况基本上不会发生。

因此处理物化视图高水位线最稳妥的方法还是使用MOVE的方式。

 

 

 

物化视图的非原子性刷新

物化视图的原子性刷新是指在刷新一组物化视图的时候,整个刷新作为一个事务,如果其中一个物化视图刷新失败,那么这一组物化视图都不会刷新。非原子性刷新则指的是每个物化视图会作为一个单独的事务,如果一组物化视图进行刷新,其中某个物化视图刷新失败,那么前面已经刷新过的物化视图都是提交过的。

 

 

对于完全刷新来说,非原子性刷新是最佳选择。由于原子性刷新会采用DELETEINSERT的方法,完全刷新将会删除物化视图表中所有的数据,然后在将源表中所有输入插入到物化视图表中,且这些DML都会使用UNDO空间,不但效率很低,而且占用大量的资源。

而非原子性刷新则采用了TRUNCATE+ INSERT /*+ APPEND */的方法。以前只是注意到了TRUNCATE,没有注意这个APPEND。最近由于在一个小的测试环境下完全刷新一张很大的表,由于表本身的大小已经接近了这个数据库中UNDO表空间的大小,所以采用平常的刷新方式无法成功。当时就在想办法,看看能不能将物化视图的INSERT变成APPEND方式,结果TRACE了一下非原子性的刷新方式,发现Oracle自动采用了APPEND的方式。这样非原子性刷新不但效率最高,而且将占有的UNDO空间和产生的REDO数量减少到最低的情况。

SQL> CREATE TABLE T (ID NUMBER,NAME VARCHAR2(30));

表已创建。

SQL> ALTER TABLE T ADD CONSTRAINTPK_T PRIMARY KEY (ID);

表已更改。

SQL> CREATE MATERIALIZED VIEW LOGON T;

实体化视图日志已创建。

SQL> DROP MATERIALIZED VIEW LOGON T;

实体化视图日志已删除。

SQL> CREATE MATERIALIZED VIEWMV_T REFRESH COMPLETE AS SELECT * FROM T;

实体化视图已创建。

SQL> INSERT INTO T SELECT ROWNUM,TNAME FROM TAB;

已创建23行。

SQL> COMMIT;

提交完成。

SQL> ALTER SESSION SET SQL_TRACE= TRUE;

会话已更改。

SQL> EXECDBMS_MVIEW.REFRESH('MV_T')

PL/SQL 过程已成功完成。

SQL> EXECDBMS_MVIEW.REFRESH('MV_T', ATOMIC_REFRESH => FALSE)

PL/SQL 过程已成功完成。

SQL> ALTER SESSION SET SQL_TRACE= FALSE;

会话已更改。

查看得到的TRACE文件信息:

=====================
PARSING IN CURSOR #3 len=34 dep=0 uid=72 ct=42 lid=72 tim=229649519499hv=3913151867 ad='2567fa48'
ALTER SESSION SET SQL_TRACE = TRUE
END OF STMT
EXEC #3:c=0,e=288,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=229649519493
*** 2008-11-12 08:40:28.078
=====================
PARSING IN CURSOR #15 len=198 dep=1 uid=0 ct=3 lid=0 tim=229660972725hv=4125641360 ad='336db980'
select obj#,type#,ctime,mtime,stime,status,dataobj#,flags,oid$, spare1, spare2from obj$ where owner#=:1 and name=:2 and namespace=:3 and remoteowner is nulland linkname is null and subname is null
END OF STMT
PARSE #15:c=0,e=380,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=229660972719
EXEC #15:c=0,e=31901,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=229661005512
FETCH #15:c=0,e=46,p=0,cr=2,cu=0,mis=0,r=0,dep=1,og=4,tim=229661005771
STAT #15 id=1 cnt=0 pid=0 pos=1 bj=18 p='TABLE ACCESS BY INDEX ROWID OBJ$ (cr=2pr=0 pw=0 time=54 us)'
STAT #15 id=2 cnt=0 pid=1 pos=1 bj=37 p='INDEX RANGE SCAN I_OBJ2 (cr=2 pr=0pw=0 time=37 us)'
=====================
.
.
.
=====================
PARSING IN CURSOR #19 len=28 dep=1 uid=72 ct=7 lid=72 tim=229662296277hv=4184353949 ad='25464a68'
 delete from "YANGTK"."MV_T"
END OF STMT
PARSE #19:c=0,e=2951,p=0,cr=14,cu=0,mis=1,r=0,dep=1,og=1,tim=229662296271
EXEC #19:c=0,e=174,p=0,cr=3,cu=0,mis=0,r=0,dep=1,og=1,tim=229662296519
=====================
.
.
.
=====================
PARSING IN CURSOR #19 len=110 dep=1 uid=72 ct=2 lid=72 tim=229662306090hv=3172137641 ad='25463ee8'
INSERT /*+ BYPASS_RECURSIVE_CHECK */ INTO"YANGTK"."MV_T"("ID","NAME") SELECT"T"."ID","T"."NAME" FROM "T""T"
END OF STMT
PARSE #19:c=0,e=1623,p=0,cr=8,cu=0,mis=1,r=0,dep=1,og=1,tim=229662306084
EXEC #19:c=0,e=359,p=0,cr=8,cu=21,mis=0,r=23,dep=1,og=1,tim=229662306510
STAT #19 id=1 cnt=23 pid=0 pos=1 bj=61746 p='TABLE ACCESS FULL T (cr=7 pr=0pw=0 time=140 us)'
STAT #28 id=1 cnt=1 pid=0 pos=1 bj=0 p='UPDATE  SNAP$ (cr=1 pr=0 pw=0time=80 us)'
STAT #28 id=2 cnt=1 pid=1 pos=1 bj=217 p='INDEX UNIQUE SCAN I_SNAP1 (cr=1 pr=0pw=0 time=25 us)'
=====================
.
.
.
=====================
PARSING IN CURSOR #30 len=50 dep=1 uid=72 ct=85 lid=72 tim=229677074850hv=3299608286 ad='25460cfc'
 truncate table "YANGTK"."MV_T" purge snapshot log
END OF STMT
PARSE #30:c=0,e=58160,p=0,cr=0,cu=1,mis=1,r=0,dep=1,og=1,tim=229677074843
=====================
.
.
.
=====================
PARSING IN CURSOR #30 len=139 dep=1 uid=72 ct=2 lid=72 tim=229678096349hv=1058017291 ad='25799364'
INSERT /*+ BYPASS_RECURSIVE_CHECK APPEND SKIP_UNQ_UNUSABLE_IDX */ INTO"YANGTK"."MV_T"("ID","NAME") SELECT"T"."ID","T"."NAME" FROM "T""T"
END OF STMT
PARSE #30:c=0,e=2970,p=0,cr=19,cu=0,mis=1,r=0,dep=1,og=1,tim=229678096342
EXEC #30:c=0,e=71106,p=1,cr=8,cu=10,mis=0,r=23,dep=1,og=1,tim=229678167508
XCTEND rlbk=0, rd_only=0
STAT #30 id=1 cnt=1 pid=0 pos=1 bj=0 p='LOAD AS SELECT  (cr=8 pr=1 pw=1time=71006 us)'
STAT #30 id=2 cnt=23 pid=1 pos=1 bj=61746 p='TABLE ACCESS FULL T (cr=7 pr=0pw=0 time=194 us)'
STAT #23 id=1 cnt=1 pid=0 pos=1 bj=0 p='UPDATE  SNAP$ (cr=1 pr=0 pw=0time=63 us)'
STAT #23 id=2 cnt=1 pid=1 pos=1 bj=217 p='INDEX UNIQUE SCAN I_SNAP1 (cr=1 pr=0pw=0 time=18 us)'
=====================
.
.
.
=====================
PARSING IN CURSOR #41 len=35 dep=0 uid=72 ct=42 lid=72 tim=229682775142hv=4067503723 ad='2579c394'
ALTER SESSION SET SQL_TRACE = FALSE
END OF STMT
PARSE #41:c=0,e=930,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=229682775135
EXEC #41:c=0,e=263,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=229682775481

TRACE信息中可以清晰的看到原子性刷新与非原子性刷新在执行方式上的区别。

 


my oracle support : 文档 ID 236233.1



0 0
原创粉丝点击