備忘録

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

元表から複数のマテビュー作成

1つのマテビューログから複数のマテビューを作った時に、マテビューログがどのような状態になるか試してみた。
結論から言うと、関連するマテビューがリフレッシュされることで不要となるログから順次消されていく。

1.TBL01 → MV01, MV02 作成
2.TBL01 に2件INSERT。マテビューログは2件
3.MV01リフレッシュ(2件)、MV02は0件のまま。マテビューログは2件
4.TBL01 に1件INSERT。マテビューログは3件
5.MV02リフレッシュ。MV01:2件、MV02:3件。マテビューログは1件
6.MV01リフレッシュ。MV01:3件、MV02:3件。マテビューログは0件
という動きになった。ローカルのマテビューなので、DBリンク越しでいろんなインスタンスからマテビューを作った時にどういう動きになるかは不明。レプリケーション関連のマニュアルを見ないとわからないと思われる。

SQL> drop table tbl01;

表が削除されました。

SQL> create table tbl01 (
2 n1 number(10)
3 ,c varchar2(10)
4 );

表が作成されました。

SQL> ALTER TABLE tbl01 ADD CONSTRAINT PK_TBL01 PRIMARY KEY(n1)

表が変更されました。

SQL> CREATE MATERIALIZED VIEW LOG ON TBL01 WITH PRIMARY KEY;

マテリアライズド・ビュー・ログが作成されました。

SQL>
SQL>
SQL> drop MATERIALIZED VIEW MV01;

マテリアライズド・ビューが削除されました。

SQL> drop MATERIALIZED VIEW MV02;

マテリアライズド・ビューが削除されました。

SQL>
SQL> CREATE MATERIALIZED VIEW MV01 REFRESH FAST AS
2 select n1 from tbl01;

マテリアライズド・ビューが作成されました。

SQL>
SQL> CREATE MATERIALIZED VIEW MV02 REFRESH FAST AS
2 select n1,c from tbl01;

マテリアライズド・ビューが作成されました。

SQL>
SQL> exec DBMS_MVIEW.REFRESH('MV01', 'f');

PL/SQLプロシージャが正常に完了しました。

SQL> exec DBMS_MVIEW.REFRESH('MV02', 'f');

PL/SQLプロシージャが正常に完了しました。

SQL>
SQL> insert into tbl01 values(1,1);

1行が作成されました。

SQL> insert into tbl01 values(2,2);

1行が作成されました。

SQL> commit;

コミットが完了しました。

SQL>
SQL> exec DBMS_MVIEW.REFRESH('MV01', 'f');

PL/SQLプロシージャが正常に完了しました。

SQL>
SQL> -- MV01 のみ更新なのでMLOGに全件残っている
SQL> select count(*) from MLOG$_TBL01;

COUNT(*)
----------
2

SQL>
SQL> insert into tbl01 values(3,1);

1行が作成されました。

SQL> commit;

コミットが完了しました。

SQL>
SQL> -- 2 + 1 で3件
SQL> select count(*) from MLOG$_TBL01;

COUNT(*)
----------
3

SQL>
SQL> exec DBMS_MVIEW.REFRESH('MV02', 'f');

PL/SQLプロシージャが正常に完了しました。

SQL>
SQL> -- MV02 を更新したので、後で入れた1件のみ残っている
SQL> select count(*) from MLOG$_TBL01;

COUNT(*)
----------
1

SQL>
SQL> exec DBMS_MVIEW.REFRESH('MV01', 'f');

PL/SQLプロシージャが正常に完了しました。

SQL>
SQL> -- 関連するマテビューをずべてリフレッシュしたので0件
SQL> select count(*) from MLOG$_TBL01;

COUNT(*)
----------
0


ついでに、sql traceをとって内部で発行されているSQLを見てみた。
今回つかった、MV01/MV02/TBL01/MLOG$_TBL01二関連するSQLだけ抜いてみた。
MV01へのDELETEやMERGEは理解できるが、2100年で引っ掛けているのは何だろう。2100年問題が起きるんでしょうかね。どうせなら、9000年とかにしておけばいいのに。

update "TEST"."MLOG$_TBL01" set snaptime$$ = :1  
where
snaptime$$ > to_date('2100-01-01:00:00:00','YYYY-MM-DD:HH24:MI:SS')

SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE
NO_PARALLEL(SAMPLESUB) opt_param('parallel_execution_enabled', 'false')
NO_PARALLEL_INDEX(SAMPLESUB) NO_SQL_TUNE */ NVL(SUM(C1),0), NVL(SUM(C2),0)
FROM
(SELECT /*+ IGNORE_WHERE_CLAUSE NO_PARALLEL("MLOG$_TBL01")
FULL("MLOG$_TBL01") NO_PARALLEL_INDEX("MLOG$_TBL01") */ 1 AS C1, CASE WHEN
"MLOG$_TBL01"."SNAPTIME$$">TO_DATE(' 2100-01-01 00:00:00', 'syyyy-mm-dd
hh24:mi:ss') THEN 1 ELSE 0 END AS C2 FROM "TEST"."MLOG$_TBL01"
"MLOG$_TBL01") SAMPLESUB

ALTER SUMMARY "TEST"."MV01" COMPILE

DELETE FROM "TEST"."MV01" SNAP$
WHERE
"N1" IN (SELECT DISTINCT MLOG$."N1" FROM "TEST"."MLOG$_TBL01" MLOG$ WHERE
"SNAPTIME$$" > :1 AND ("DMLTYPE$$" != 'I'))

MERGE INTO "TEST"."MV01" "SNA$" USING (SELECT CURRENT$."N1" FROM (SELECT
"TBL01"."N1" "N1" FROM "TBL01" "TBL01") CURRENT$, (SELECT DISTINCT
MLOG$."N1" FROM "TEST"."MLOG$_TBL01" MLOG$ WHERE "SNAPTIME$$" > :1 AND
("DMLTYPE$$" != 'D')) LOG$ WHERE CURRENT$."N1" = LOG$."N1")"AV$" ON
("SNA$"."N1" = "AV$"."N1") WHEN MATCHED THEN UPDATE SET "SNA$"."N1" =
"AV$"."N1" WHEN NOT MATCHED THEN INSERT (SNA$."N1") VALUES (AV$."N1")

delete from "TEST"."MLOG$_TBL01"
where
snaptime$$ <= :1

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://ncdkayak.blog.fc2.com/tb.php/20-36ae4462
この記事にトラックバックする(FC2ブログユーザー)

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。