Oracle(11.2.0.4)マテリアライズドビューからデータを取得しているアプリケーションがあります。関連するテーブルまたは関連付けられたオブジェクトでDMLアクションが発生すると、マテリアライズドビューの動作が無効になります。
私のマテリアライズドビューの候補は以下のとおりであり、関連するオブジェクトが常に有効であることを確認しています。
CREATE materialized VIEW mv_emp_test1
NOLOGGING COMPRESS build IMMEDIATE
REFRESH FORCE
START WITH (SYSDATE) NEXT (SYSDATE+5/1024)
as
......
マテリアライズドビューは、5分ごとに更新されるとINVALID状態になり、次のいずれかの方法が適用されると有効になります。
alter materialized view mv_emp_test1 recompile;
or
exec dbms_mview.refresh('mv_emp_test1');
また、関連ドキュメントとバグを確認しました。metalinkのDoc ID 264036.1には正確なシナリオが含まれていますが、適切な回避策が見つからなかったため、5分ごとに自動更新されます。
それが予想される動作です。
ベーステーブルのデータが変更され、ビューが最新ではなくなった場合、ステータスは無効になります。再コンパイルまたは更新すると、最新の状態になり、再び有効になります。したがって、ビューの無効な状態を気にする必要はありません。
この質問はすでにstackoverfow.comで提起されており、 Andrew Brennan によって回答されています。
MOS Doc ID 264036.1を参照してください:
MVに関連する依存関係は自動的に維持され、正しく動作します。 MVが作成されると、マテリアライズドビューはその定義で参照されるマスターテーブルに依存します。マテリアライズドビューの依存関係に対するINSERT、DELETE、UPDATE、DDL操作などのDML操作は、無効になります。
マテリアライズドビューの背後にある全体的なアイデアは、ビューでデータを「利用可能」にすることであり、たとえばリモートの場所など、基礎となるテーブルからデータを取得する必要はありません。データまたはテーブル定義が変更されると、MVはINVALIDになります。
(以前のバージョンではスナップショットと呼ばれていました)
マテリアライズドビューの定義は、元のドキュメントにあります:
最新のデータを取得する場合は、通常のビューまたは同期レプリケーションの使用を検討してください。
マテリアライズドビューを自動的に更新する場合は、 JOB_QUEUE_PROCESSES を1以上の値に設定する必要があります。
おそらくジョブキュープロセスが不足していますか?
SQL> alter system set job_queue_processes=0;
System altered.
SQL> select * from test;
ID
----------
1
2
3
4
SQL> Create Materialized view test_mv
refresh complete
start with (sysdate)
next (sysdate+1/1440)
with rowid
as
select * from test;
Materialized view created.
SQL> select compile_state from dba_mviews where mview_name='TEST_MV';
COMPILE_STATE
-------------------
VALID
SQL> select * from test_mv;
ID
----------
1
2
3
4
SQL> insert into test values(5);
1 row created.
SQL> commit;
Commit complete.
SQL> select compile_state from dba_mviews where mview_name='TEST_MV';
COMPILE_STATE
-------------------
NEEDS_COMPILE
1分間お待ちください...
SQL> select * from test_mv;
ID
----------
1
2
3
4
変更はまだ反映されていません。
SQL> exec dbms_mview.refresh('TEST_MV');
PL/SQL procedure successfully completed.
SQL> select compile_state from dba_mviews where mview_name='TEST_MV';
COMPILE_STATE
-------------------
VALID
現在、これは有効な状態です。
他の人が述べたように、NEEDS_COMPILE
状態になるのはMVの予想される動作です。ただし、MVは5分間隔で自動的に更新されます。
SQL> alter system set job_queue_processes=1000;
System altered.
SQL> select compile_state from dba_mviews where mview_name='TEST_MV';
COMPILE_STATE
-------------------
VALID
SQL> insert into test values(6);
1 row created.
SQL> commit;
Commit complete.
SQL> select compile_state from dba_mviews where mview_name='TEST_MV';
COMPILE_STATE
-------------------
NEEDS_COMPILE
ちょっと待って...
SQL> /
COMPILE_STATE
-------------------
VALID
有効になりました。