到目前为止,还没有看到过物化视图日志的清除,其实每次进行完刷新,物化视图日志都会试图删除没有用的物化视图日志记录。物化视图日志记录的删除条件是删除那些SNAPTIME$$列小于等于基表所有物化视图的上次刷新时间。在上面的例子中,由于MV_T_BOTH一直没有刷新,因此它的LAST_REFRESH_DATE比物化视图日志中所有记录的值都小,因此,一直没有发生物化视图日志记录清除的现象。
zx@ORA11G>insert into t values (5, 'zq', 'jx');
1 row created.
zx@ORA11G>commit;
Commit complete.
zx@ORA11G>exec dbms_mview.refresh('MV_T_BOTH');
PL/SQL procedure successfully completed.
zx@ORA11G>select mview_name,last_refresh_date, staleness from user_mviews;
MVIEW_NAME LAST_REFRESH_DATE STALENESS
------------------------------ ----------------- -------------------
MV_T_BOTH 20170809 16:19:51 FRESH
MV_T_ID 20170809 16:17:43 NEEDS_COMPILE
MV_T_NAME 20170809 16:16:01 NEEDS_COMPILE
zx@ORA11G>select * from mlog$_t;
ID NAME M_ROW$$ SEQUENCE$$ SNAPTIME$$ D O CHANGE_VECTOR$$ XID$$
-------------------- ---------- ------------------------------ -------------------- ----------------- - - ------------------------------ --------------------
5 zq AAAVs6AAEAAAAJVAAE 15 20170809 16:19:51 I N FE 2251898597934032
物化视图MV_T_BOTH刷新了物化视图中的每条记录,更新了ID=5的记录的SNAPTIME$$时间,并清除了其它所有物化视图日志记录。
总结:
物化视图在刷新时,会刷新所有SNAPTIME$$大于本物化视图上次刷新时间的记录,并将所有是40000101 00:00:00的记录更新为当前刷新时间。对于其他大于上次刷新时间的记录,只刷新不更改。这样,当刷新执行完以后,数据字典中记录当前物化视图的上次刷新时间为当前时刻,这保证了物化视图日志中目前所有的记录都小于或等于刷新时间。因此,每个物化视图只要刷新大于上次刷新时间的记录,且保证每次刷新后,所有记录的时间都小于等于上次刷新时间,那么无论有多少个物化视图,就可以互不影响的使用同一个物化视图日志进行快速刷新了。当物化视图刷新完之后,会清除那些SNAPTIME$$列小于所有物化视图的上次刷新时间的记录,而这些记录已经被所有的物化视图都刷新过了,保存在物化视图日志中已经没有意义了。