マテビュー覚え書き
次の現場でマテビューことマテリアライズド・ビューを使うことになりそうだったのでメモ代り。ちなみに就職して始めてはいった現場がOracle 8iだったため、いまでも惰性で待てマテリアライズド・ビューのことを「スナップショット」と呼んでしまう悲しい三十代が僕ですが何か?
一噛みして気が済んだので、メモ
1.まずはマスター表(同期元)になる表を作成
SQL> create table mateview_master ( 2 col1 date, 3 col2 number(8), 4 col3 number(8), 5 col4 char(9), 6 col5 number(8) 7 ); 表が作成されました。
2.ついでなんでこの時点でマスター表にデータも突っ込んじゃう
SQL> begin 2 for i in 1..10000 loop 3 insert into mateview_master values ( 4 sysdate + i/3600, 5 i, 6 i * 2, 7 to_char(sysdate + i/3600), 8 i 9 ) ; 10 end loop ; 11 commit; 12 end; 13 / PL/SQLプロシージャが正常に完了しました。
3.高速リフレッシュ(差分同期)させたいのでマテリアライズド・ビュー・ログを作成します
SQL> create materialized view log on mateview_master ; マテリアライズド・ビュー・ログが作成されました。
4.お待ちかね。マテリアライズド・ビュー(同期先)を作成します
SQL> create materialized view mateview_replica 2 as 3 select col1, col3, col5 from mateview_master 4 where col5 < 100000 5 ; マテリアライズド・ビューが作成されました。
5.作成時点でのデータ件数を確認(マテビュー名の後ろに"BUILD DEFERRED"を指定していないので、データは入ってるはず)
SQL> select count(*) from mateview_replica ; COUNT(*) ---------- 10000
入ってますな。
6.マスター表に項目4のwhere句境界をまたがるデータを追加してみる。
SQL> begin 2 for i in 95000..105000 loop 3 insert into mateview_master values( 4 sysdate + i/3600, 5 i, 6 i * 2, 7 to_char(sysdate + i/3600), 8 i 9 ); 10 end loop ; 11 commit ; 12 end; 13 / PL/SQLプロシージャが正常に完了しました。
7.リフレッシュ(同期)してないのでまだ件数は変わらない
SQL> select count(*) from mateview_replica ; COUNT(*) ---------- 10000
8.リフレッシュしてみる。まずは完全リフレッシュ(完全同期)
SQL> exec dbms_mview.refresh('mateview_replica', 'c') ; PL/SQLプロシージャが正常に完了しました。 SQL> select count(*) from mateview_replica ; COUNT(*) ---------- 15000
反映(実際にはマテビューデータを全消去してからマスター表のデータを入れている)されてる
9.続いて高速リフレッシュ(差分同期)
SQL> exec dbms_mview.refresh('mateview_replica', 'f') ; PL/SQLプロシージャが正常に完了しました。 SQL> select count(*) from mateview_replica ; COUNT(*) ---------- 15000
まぁ、差分無いからねぇ……。
10.今回作成したのは「読み取り専用マテリアライズド・ビュー」なのでDML操作は無効になる
SQL> insert into mateview_replica values ( 2 sysdate, 2, 0 3 ) ; insert into mateview_replica values ( * 行1でエラーが発生しました。: ORA-01732: このビューではデータ操作が無効です SQL> delete from mateview_replica ; delete from mateview_replica * 行1でエラーが発生しました。: ORA-01732: このビューではデータ操作が無効です SQL> update mateview_replica set col1=sysdate ; update mateview_replica set col1=sysdate * 行1でエラーが発生しました。: ORA-01732: このビューではデータ操作が無効です
11.でもtruncateは通っちゃう
SQL> truncate table mateview_replica ; 表が切り捨てられました。 SQL> select count(*) from mateview_replica ; COUNT(*) ---------- 0
12.この状態で高速リフレッシュをやると、怒られる
SQL> exec dbms_mview.refresh('mateview_replica', 'f') ; BEGIN dbms_mview.refresh('mateview_replica', 'f') ; END; * 行1でエラーが発生しました。: ORA-32320: "KWY"."MATEVIEW_REPLICA"のREFRESH FASTはコンテナ表PMOPの後ではサポートされていません ORA-06512: "SYS.DBMS_SNAPSHOT", 行2537 ORA-06512: "SYS.DBMS_SNAPSHOT", 行2743 ORA-06512: "SYS.DBMS_SNAPSHOT", 行2712 ORA-06512: 行1
エラーメッセージとしてはORA-32321が出るのが正しいような気もするんだけど、まぁORA-32320が出る。対処方の完全リフレッシュ実施は、まぁ、その通りなんだけど。
$ oerr ora 32320 32320, 00000, "REFRESH FAST of \"%s\".\"%s\" unsupported after container table PMOPs" // *Cause: A Partition Maintenance Operation (PMOP) has been performed on the // materialized view, and no materialized view supports // fast refersh after container table PMOPs. // *Action: Use REFRESH COMPLETE. Note: you can determine why your // materialized view does not support fast refresh after PMOPs using // the DBMS_MVIEW.EXPLAIN_MVIEW() API. $ $ $ oerr ora 32321 32321, 00000, "REFRESH FAST of \"%s\".\"%s\" unsupported after detail table TRUNCATE" // *Cause: A detail table has been truncated and no materialized view // supports fast refersh after a detail table has been truncated // *Action: Use REFRESH COMPLETE. Note: you can determine why your // materialized view does not support fast refresh after TRUNCATE using // the DBMS_MVIEW.EXPLAIN_MVIEW() API.
こんな感じ。