マテリアライズド・ビューのリフレッシュ動作を試す

# マテリアライズド・ビューのリフレッシュ
 マテリアライズド・ビューの手動リフレッシュは DBMS_MVIEW パッケージ（マテリアライズド・ビュー・グループの場合は DBMS_REFRESH）パッケージの REFRESH プロシージャで行います。リフレッシュ方法は method パラメータに以下の種類を指定します。

|メソッド|説明|
|:---|:---|
|f|高速リフレッシュ|
|?|強制リフレッシュ（高速または完全を自動選択）|
|c または a| 完全リフレッシュ|
|p|パーティション・リフレッシュ|


```
SQL> EXECUTE DBMS_MVIEW.REFRESH('MVIEW1', 'c');

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

# アトミックなリフレッシュ
  デフォルトではリフレッシュ処理は単一トランザクションで実行されます。この動作は atomic_refresh オプションに false を指定することで変更できます。完全リフレッシュの場合、atomic_refresh を変更することで以下のように内部動作が変更されます。
  
## atomic_refresh := TRUE
デフォルトではマテリアライズド・ビューの全件削除には DELETE 文が実行されます。以下は、トレースファイルからの抜粋です。

```
BEGIN DBMS_MVIEW.REFRESH(list=>'MVIEW1', method=>'c', atomic_refresh=>TRUE);
  END;

COMMIT WORK

delete from "SCOTT"."MVIEW1"

INSERT /*+ BYPASS_RECURSIVE_CHECK */ INTO "SCOTT"."MVIEW1"("C1","C2") SELECT
  "MTABLE1"."C1","MTABLE1"."C2" FROM "MTABLE1"@"LINK1" "MTABLE1"

```

## atomin_refresh := FALSE
atomic_refresh オプションに false を指定すると、マテリアライズド・ビューのデータ削除には TRUNCATE 文が実行されます。またマテリアライズド・ビューをロックし、インデックスの再構築を行っていることがわかります。

```
BEGIN DBMS_MVIEW.REFRESH(list=>'MVIEW1', method=>'c', atomic_refresh=>FALSE);
  END;

SET CONSTRAINTS ALL DEFERRED

LOCK TABLE "SCOTT"."MVIEW1" IN EXCLUSIVE MODE  NOWAIT

truncate table "SCOTT"."MVIEW1" purge snapshot log

LOCK TABLE  FOR INDEX "SCOTT"."SYS_C007867" IN EXCLUSIVE MODE  NOWAIT

ALTER INDEX "SCOTT"."SYS_C007867" UNUSABLE

INSERT /*+ BYPASS_RECURSIVE_CHECK APPEND SKIP_UNQ_UNUSABLE_IDX */ INTO
  "SCOTT"."MVIEW1"("C1","C2") SELECT "MTABLE1"."C1","MTABLE1"."C2" FROM
  "MTABLE1"@"LINK1" "MTABLE1"

ALTER INDEX "SCOTT"."SYS_C007867" REBUILD  NOPARALLEL

```

# アウトオブプレースなリフレッシュ
 デフォルトではマテリアライズド・ビューの更新処理は、マテリアライズド・ビューを直接更新します。この動作をインプレース・リフレッシュと呼びます。オプション out_of_replace に TRUE を指定すると、別の領域を使ってマテリアライズド・ビューの更新を行います。

## アウトオブプレース・リフレッシュの実行条件
　アウトオブプレース・リフレッシュが実行されるにはいくつか条件があります。

- アトミックなリフレッシュではないこと（atomic_refresh := false）
- 結合または集約が含まれること
- ローカル・マテリアライズド・ビューであること
- LOB データを含まないこと
- その他

条件に合わない場合、以下のようなわかりにくいエラーが発生します。

```
SQL> EXEC DBMS_MVIEW.REFRESH(list=>'MVIEW3', method=>'?', atomic_refresh=>FALSE, out_of_place=>TRUE);
BEGIN DBMS_MVIEW.REFRESH(list=>'MVIEW3', method=>'?', atomic_refresh=>FALSE, out_of_place=>TRUE); END;

*
行1でエラーが発生しました。:
ORA-32354:
ホーム外の完全リフレッシュを使用して、マテリアライズド・ビューSCOTT.MVIEW3をリフ
レッシュできません
ORA-06512: "SYS.DBMS_SNAPSHOT_KKXRCA", 行3012
ORA-06512: "SYS.DBMS_SNAPSHOT_KKXRCA", 行2424
ORA-06512: "SYS.DBMS_SNAPSHOT_KKXRCA", 行88
ORA-06512: "SYS.DBMS_SNAPSHOT_KKXRCA", 行253
ORA-06512: "SYS.DBMS_SNAPSHOT_KKXRCA", 行2405
ORA-06512: "SYS.DBMS_SNAPSHOT_KKXRCA", 行2968
ORA-06512: "SYS.DBMS_SNAPSHOT_KKXRCA", 行3255
ORA-06512: "SYS.DBMS_SNAPSHOT_KKXRCA", 行3287
ORA-06512: "SYS.DBMS_SNAPSHOT", 行16
ORA-06512: 行1
```

## アウトオブプレース・リフレッシュの内部
  アウトオブプレース・リフレッシュを実行する場合は、一時的にRVではじまる同一構成のテーブルを作成し、こちらのテーブルにデータを格納します。一時的なテーブルをマテリアライズド・ビューとして登録する部分はトレースからは見つけられませんでした。

```
BEGIN DBMS_MVIEW.REFRESH(list=>'MVIEW3', method=>'c', atomic_refresh=>FALSE,
  out_of_place=>TRUE); END;

COMMIT WORK

SET CONSTRAINTS ALL DEFERRED

drop table "SCOTT"."RV$12A21"

CREATE TABLE RV$12A21 ("SUM1")  SEGMENT CREATION IMMEDIATE  AS SELECT  * FROM
 (SELECT SUM("DATA1"."C1") "SUM1" FROM "DATA1" "DATA1") WHERE 1 = NULL

INSERT /*+ APPEND */ INTO "SCOTT"."RV$12A21" ("SUM1") SELECT SUM("DATA1"."C1")
 FROM "DATA1" "DATA1"

COMMENT ON MATERIALIZED VIEW RV$12A21 IS 'snapshot table for snapshot SCOTT.MVIEW3'

ALTER TABLE "SCOTT"."RV$12A21" RENAME TO "BIN$nMivZlFqMIXgVZIT1Vswrg==$0"

ALTER SUMMARY "SCOTT"."MVIEW3" COMPILE

```