Материализованные представления: как найти количество обновлений, вставок и удалений, применяемых во время обновления?

У меня есть Data mart, освоенный из нашей базы данных OLTP Oracle, используя основные материализованные представления с возможностью быстрого обновления по требованию. Обновление работает нормально. Мне интересно добавить некоторые статистические данные об обновлении каждого материализованного представления, такие как количество вставок, обновлений и удалений, которые были применены к главной таблице с момента последнего обновления, как эти данные, которые я могу найти в user_tab_modifications. Возможно ли это для материализованных взглядов?

1 ответов


перед выполнением обновления вы можете запросить журнал материализованного представления, чтобы узнать, какие векторы изменений он хранит. Это будут векторы изменений, которые необходимо применить к материализованному представлению во время процесса обновления (при условии, что существует только одно материализованное представление, зависящее от этого журнала материализованного представления).

например, если я создаю свою таблицу, мой материализованный журнал представлений и мое материализованное представление.

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

теперь, если я вставлю новую строку в таблицу, я увижу строку в материализованном журнале просмотра с DMLTYPE$$ of I С указанием 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;