2012-03-21 61 views
6

我有一個從我們的OLTP Oracle數據庫掌握的數據集市,使用具有按需快速刷新功能的基本物化視圖。刷新工作正常。我有興趣添加的是關於每個物化視圖刷新的一些統計信息,例如自上次刷新以來應用於主表的插入,更新和刪除的數量,如我在user_tab_modifications中可以找到的數據。物化視圖可能嗎?物化視圖:如何查找刷新期間應用的更新,插入和刪除的數量?

回答

6

在刷新之前,您可以查詢物化視圖日誌以查看它存儲的變化向量。這些將是刷新過程中需要應用到物化視圖的變化向量(假設只有一個物化視圖依賴於此物化視圖日誌)。

例如,如果我創建我的表,物化視圖日誌和物化視圖。

SQL> create table foo(col1 number primary key); 

Table created. 

SQL> create materialized view log on foo; 

Materialized view log created. 


SQL> ed 
Wrote file afiedt.buf 

    1 create materialized view mv_foo 
    2 refresh fast on demand 
    3 as 
    4 select * 
    5* from foo 
SQL>/

Materialized view created. 

SQL> insert into foo values(1); 

1 row created. 

SQL> insert into foo values(2); 

1 row created. 

SQL> commit; 

Commit complete. 

現在,我刷新物化視圖,並確認表和物化視圖是同步的

SQL> exec dbms_mview.refresh('MV_FOO'); 

PL/SQL procedure successfully completed. 

SQL> select * from user_tab_modifications where table_name = 'MV_FOO'; 

no rows selected 

SQL> select * from foo; 

     COL1 
---------- 
     1 
     2 

SQL> select * from mv_foo; 

     COL1 
---------- 
     1 
     2 

由於這兩個對象是同步的,物化視圖日誌是空(物化查看日誌將被命名爲MLOG$_<<table name>>

SQL> select * from mlog$_foo; 

no rows selected 

現在,如果我插入一個新行到表中,我可以看到在物化視圖日誌行與的指示INSERT

SQL> insert into foo values(3); 

1 row created. 

SQL> select * from mlog$_foo; 

     COL1 SNAPTIME$ D O 
---------- --------- - - 
CHANGE_VECTOR$$ 
-------------------------------------------------------------------------------- 
    XID$$ 
---------- 
     3 01-JAN-00 I N 
FE 
2.2519E+15 

所以你可以做這樣的事情來獲得掛起的插入,更新的數量,並刪除。

SELECT SUM(CASE WHEN dmltype$$ = 'I' THEN 1 ELSE 0 END) num_pending_inserts, 
     SUM(CASE WHEN dmltype$$ = 'U' THEN 1 ELSE 0 END) num_pending_updates, 
     SUM(CASE WHEN dmltype$$ = 'D' THEN 1 ELSE 0 END) num_pending_deletes 
    FROM mlog$_foo 

但是,刷新物化視圖日誌後,此信息就消失了。

另一方面,USER_TAB_MODIFICATIONS應跟蹤自上次收集統計信息以來對物化視圖所做的更改的近似數量,就像跟蹤表的信息一樣。如果要在刷新實體化視圖之前和之後捕獲數據,幾乎可以肯定需要調用DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO以強制數據顯示。

SELECT inserts, updates, deletes 
    INTO l_starting_inserts, 
     l_starting_updates, 
     l_starting_deletes 
    FROM user_tab_modifications 
WHERE table_name = 'MV_FOO'; 

dbms_mview.refresh('MV_FOO'); 
dbms_stats.flush_database_monitoring_info; 

SELECT inserts, updates, deletes 
    INTO l_ending_inserts, 
     l_ending_updates, 
     l_ending_deletes 
    FROM user_tab_modifications 
WHERE table_name = 'MV_FOO'; 

l_incremental_inserts := l_ending_inserts - l_starting_inserts; 
l_incremental_updates := l_ending_updates - l_starting_updates; 
l_incremental_deletes := l_ending_deletes - l_starting_deletes; 
+0

謝謝你這個非常深入的答案! – user1284595 2012-03-22 14:59:06