<script type="text/javascript">
</script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
探讨实体化视图的 刷新机制
Author:Kamus
Mail:kamus@itpub.net
Date:2004年10月
今天给客户搭建历史查询服务器,用oracle8i的snapshot实现,也就是9i的实体化视图。
顺手做了一下trace,看了一下刷新时候oracle后台是怎么工作的。
前期准备,使用DBMS_SUPPORT包,这个包默认是没有安装的,需要运行下面的命令来手动安装。
SQL>conn/assysdba
SQL>@?/rdbms/admin/dbmssupp.sql
SQL>GRANTexecuteONdbms_supportTOkamus;
SQL>CREATEPUBLICSYNONYMdbms_supportFORdbms_support;
先看快速刷新,测试表是T1,创建了快照日志,用于刷新的视图是MV_T1,用户是KAMUS
执行trace:
SQL>connkamus
SQL>execdbms_support.start_trace(waits=>TRUE,binds=>TRUE);
SQL>execdbms_mview.refresh(list=>'MV_T1');
SQL>execdbms_support.stop_trace;
然后tkprof生成trace结果的报表,下面只是节选了其中一部分。
执行一次dbms_mview.refresh,后台会执行13个user SQL和92个internalSQL,实在是一个繁杂的工作。
1。开始刷新
BEGINdbms_mview.refresh(list=>'MV_T1');END;
2。检查SNAP$表,确认当前用户是否有需要刷新的视图
3。在DBMS_LOCK_ALLOCATED数据字典中更新记录,设置过期时间
UPDATEDBMS_LOCK_ALLOCATEDSETEXPIRATION=SYSDATE+(:B1/86400)
WHERE
ROWID=:B2
4。检查可能会用到的dblink和一些高级队列的数据字典
5。检查表的相关约束
6。检查几个初始化参数的值,包括_enable_refresh_schedule,_delay_index_maintain,compatible
7。将MLOG中所有没有标志为定时刷新的记录更新为立刻刷新
update"KAMUS"."MLOG$_T1"setsnaptime$$=:1
where
snaptime$$>to_date('2100-01-01:00:00:00','YYYY-MM-DD:HH24:MI:SS')
8。重新编译MV_T1实体化视图
ALTERSUMMARY"KAMUS"."MV_T1"COMPILE
这一步比较可疑,SQL中是没有altersummary找个命令的,如果是编译的话,那么就可能锁定对象,就有可能产生librarycachelock
9。检查要执行的SQL文,这一步比较有趣
SELECToperation#,cols,sql_txt,tabnum,fcmaskvec,ejmaskvec,setnum
FROM
sys.snap_refop$ WHERE((operation#>=0ANDoperation#<=6)ORoperation#
IN(10,12,13)) ANDsowner=:1ANDvname=:2ANDinstsite=:3 ORDER
BYtabnum,setnum,operation#
对于一个MV刷新将会使用到SQL全部存在这张表中。
如果是fast刷新,那么对于查询mlog表,查询基表的数据,insert、update、delete实体化视图都分别有一句SQL。
其中operation#字段值的常见含义如下:
0:查询mlog表
1:对于实体化视图的delete操作
2:查询基表的最新数据
3:对于实体化视图的update操作
4:对于实体化视图的insert操作
如果是complete刷新,那么只有一条记录,是基于基表的全表insert操作,operation#是7。
此处的执行计划显示是对于snap_refop$的全表扫描,如果系统中存在大量需要refresh的实体化视图,无疑是影响性能的。
10。取得需要更新的记录主键
SELECTDISTINCTLOG$."IDATE"
FROM
(SELECTMLOG$."IDATE"FROM"KAMUS"."MLOG$_T1"MLOG$WHERE"SNAPTIME$$">:1
AND("DMLTYPE$$"!='I'))LOG$WHERE(LOG$."IDATE")NOTIN(SELECT
MAS_TAB$."IDATE"FROM"T1""MAS_TAB$"WHERELOG$."IDATE"=MAS_TAB$."IDATE")
注意到这里使用了distinct,也就是我们可以猜测,如果在一次刷新之前对于同一条记录作了多次的修改,那么刷新操作只需要作一次,就是获得基表中该条记录的最新值就可以了。 1 <script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript">
</script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
探讨实体化视图的 刷新机制
Author:Kamus
Mail:kamus@itpub.net
Date:2004年10月
今天给客户搭建历史查询服务器,用oracle8i的snapshot实现,也就是9i的实体化视图。
顺手做了一下trace,看了一下刷新时候oracle后台是怎么工作的。
前期准备,使用DBMS_SUPPORT包,这个包默认是没有安装的,需要运行下面的命令来手动安装。
SQL>conn/assysdba
SQL>@?/rdbms/admin/dbmssupp.sql
SQL>GRANTexecuteONdbms_supportTOkamus;
SQL>CREATEPUBLICSYNONYMdbms_supportFORdbms_support;
先看快速刷新,测试表是T1,创建了快照日志,用于刷新的视图是MV_T1,用户是KAMUS
执行trace:
SQL>connkamus
SQL>execdbms_support.start_trace(waits=>TRUE,binds=>TRUE);
SQL>execdbms_mview.refresh(list=>'MV_T1');
SQL>execdbms_support.stop_trace;
然后tkprof生成trace结果的报表,下面只是节选了其中一部分。
执行一次dbms_mview.refresh,后台会执行13个user SQL和92个internalSQL,实在是一个繁杂的工作。
1。开始刷新
BEGINdbms_mview.refresh(list=>'MV_T1');END;
2。检查SNAP$表,确认当前用户是否有需要刷新的视图
3。在DBMS_LOCK_ALLOCATED数据字典中更新记录,设置过期时间
UPDATEDBMS_LOCK_ALLOCATEDSETEXPIRATION=SYSDATE+(:B1/86400)
WHERE
ROWID=:B2
4。检查可能会用到的dblink和一些高级队列的数据字典
5。检查表的相关约束
6。检查几个初始化参数的值,包括_enable_refresh_schedule,_delay_index_maintain,compatible
7。将MLOG中所有没有标志为定时刷新的记录更新为立刻刷新
update"KAMUS"."MLOG$_T1"setsnaptime$$=:1
where
snaptime$$>to_date('2100-01-01:00:00:00','YYYY-MM-DD:HH24:MI:SS')
8。重新编译MV_T1实体化视图
ALTERSUMMARY"KAMUS"."MV_T1"COMPILE
这一步比较可疑,SQL中是没有altersummary找个命令的,如果是编译的话,那么就可能锁定对象,就有可能产生librarycachelock
9。检查要执行的SQL文,这一步比较有趣
SELECToperation#,cols,sql_txt,tabnum,fcmaskvec,ejmaskvec,setnum
FROM
sys.snap_refop$ WHERE((operation#>=0ANDoperation#<=6)ORoperation#
IN(10,12,13)) ANDsowner=:1ANDvname=:2ANDinstsite=:3 ORDER
BYtabnum,setnum,operation#
对于一个MV刷新将会使用到SQL全部存在这张表中。
如果是fast刷新,那么对于查询mlog表,查询基表的数据,insert、update、delete实体化视图都分别有一句SQL。
其中operation#字段值的常见含义如下:
0:查询mlog表
1:对于实体化视图的delete操作
2:查询基表的最新数据
3:对于实体化视图的update操作
4:对于实体化视图的insert操作
如果是complete刷新,那么只有一条记录,是基于基表的全表insert操作,operation#是7。
此处的执行计划显示是对于snap_refop$的全表扫描,如果系统中存在大量需要refresh的实体化视图,无疑是影响性能的。
10。取得需要更新的记录主键
SELECTDISTINCTLOG$."IDATE"
FROM
(SELECTMLOG$."IDATE"FROM"KAMUS"."MLOG$_T1"MLOG$WHERE"SNAPTIME$$">:1
AND("DMLTYPE$$"!='I'))LOG$WHERE(LOG$."IDATE")NOTIN(SELECT
MAS_TAB$."IDATE"FROM"T1""MAS_TAB$"WHERELOG$."IDATE"=MAS_TAB$."IDATE")
注意到这里使用了distinct,也就是我们可以猜测,如果在一次刷新之前对于同一条记录作了多次的修改,那么刷新操作只需要作一次,就是获得基表中该条记录的最新值就可以了。 1 <script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript">
</script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>