2012-03-21 15 views
6

Tengo una base de datos masterizada desde nuestra base de datos OLTP Oracle utilizando vistas materializadas básicas con capacidad de actualización rápida bajo demanda. Actualizar funciona bien. Lo que me interesa agregar son algunas estadísticas sobre la actualización de cada Vista Materializada, como el número de insertos, actualizaciones y eliminaciones que se aplicaron a la tabla maestra desde la última actualización, como los datos que puedo encontrar en user_tab_modifications. ¿Es esto posible para Vistas Materializadas?Vistas materializadas: ¿cómo puedo encontrar la cantidad de actualizaciones, inserciones y eliminaciones aplicadas durante la actualización?

Respuesta

6

Antes de realizar la actualización, puede consultar el registro de vista materializada para ver qué tipo de vectores de cambio almacena. Esos serán los vectores de cambio que se deben aplicar a la vista materializada durante el proceso de actualización (suponiendo que solo hay una vista materializada que depende de este registro de vista materializado).

Por ejemplo, si creo mi tabla, mi registro de vista materializada y mi vista materializada.

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. 

Ahora, actualice la vista materializada y verifique que la mesa y la vista materializada están sincronizados

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 

Puesto que los dos objetos están sincronizados, el registro de vista materializada está vacía (el materializada ver registro será nombrado MLOG$_<<table name>>

SQL> select * from mlog$_foo; 

no rows selected 

Ahora, si inserto una nueva fila en la tabla, voy a ver una fila en el registro de vista materializada con un DMLTYPE$$ de I que indica un 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 

Por lo que podría hacer algo como esto para conseguir el número de pendientes inserciones, actualizaciones y eliminaciones.

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 

Una vez que actualiza el registro de la vista materializada, sin embargo, esta información se ha ido.

Por otro lado, USER_TAB_MODIFICATIONS debe realizar un seguimiento del número aproximado de cambios que se han realizado en la vista materializada desde la última vez que se recopilaron las estadísticas, de la misma manera que se seguiría la información de una tabla. Es casi seguro que deberá llamar al DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO para forzar que los datos se hagan visibles si desea capturar los datos antes y después de la actualización de la vista materializada.

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

¡Gracias por esta respuesta tan exhaustiva! – user1284595

Cuestiones relacionadas