マテリアライズドビューの完全更新または手動での同等操作のやり直しを制限する


10

マテリアライズドビュー(MV)ログを使用すると、MVは、変更されたデータのみを変更する高速リフレッシュを実行できます。ただし、さまざまな条件により、MVはログを使用できないため、完全な更新が必要です。Oracleは、すべてのレコードの削除と挿入として、アトミック完全リフレッシュを実装しました。最終的にデータに変更がない場合でも、これを行います。

このレプリケーションをREDO生成に関してインテリジェントにする方法はありますか?MERGEに続いてDELETEを実行するには、ソースを2回クエリする必要があります。BULK MERGEおよびDELETEを実行するためにデータを一括収集することは価値がありますか?もっと良い方法はありますか?

更新:

グローバル一時テーブルをステージング領域として使用することを検討しました。使用するREDOは半分未満ですが、それでも多くを使用しています。


gttコードを投稿できますか?gttはredoを直接生成しませんが、undoを生成します-undoはredoを生成します。insertopsは、deleteor updateops よりもはるかに少ないundoを生成します(実際にはほとんどありません)。高価なOPSを避けるために、複数のCisco ITPの初期導入を持つことは良いアプローチであるかもしれない
ジャックはtopanswers.xyz試し言う

@Jack Douglas psoug.org/reference/gtt.htmlには、物理テーブルとinsertsのGTTとの間でREDOが60%削減されたことを示すGTT Redo Generation Demoがあります。これは、私が見ている結果とほぼ一致しており、優れていますが、私が望むほど良くはありません。
Leigh Riffel、2011年

これらのテスト(行appendごとでヒントなし)は、やり直しを減らすための理想的な条件ではありません-私が何を意味するかを示すためにいくつかのテストを実行しました。コメントに収まらないため回答として投稿しました
ジャックはtopanswers.xyzを試してみました

回答:


5

これはinsert、質問全体に答えるのではなく、さまざまな操作のREDOの使用法を示すことだけを目的としています。私の10gインスタンスの結果は100%確定的ではありませんが、全体像は、実行するたびに同じままでした。

ヒープテーブルの場合、insert /*+ append */生成された再実行の理由がわかりません。

テストベッド:

create table heap_noappend(id integer, dummy char(500));
create table heap_append(id integer, dummy char(500));
create global temporary table gtt_noappend(id integer, dummy char(500));
create global temporary table gtt_append(id integer, dummy char(500));
create global temporary table gtt_results(stage integer, val integer);

テスト:

insert into gtt_results(stage, val)
select 0, value from v$statname join v$sesstat using(statistic#)
where sid=sys_context('userenv','sid') and name='redo size';

insert into heap_noappend(id, dummy)
select level, 'A' from dual connect by level<1000;

insert into gtt_results(stage, val)
select 1, value from v$statname join v$sesstat using(statistic#)
where sid=sys_context('userenv','sid') and name='redo size';

insert /*+ append */ into heap_append(id, dummy)
select level, 'A' from dual connect by level<1000;

insert into gtt_results(stage, val)
select 2, value from v$statname join v$sesstat using(statistic#)
where sid=sys_context('userenv','sid') and name='redo size';

insert into gtt_noappend(id, dummy)
select level, 'A' from dual connect by level<1000;

insert into gtt_results(stage, val)
select 3, value from v$statname join v$sesstat using(statistic#)
where sid=sys_context('userenv','sid') and name='redo size';

insert /*+ append */ into gtt_append(id, dummy)
select level, 'A' from dual connect by level<1000;

insert into gtt_results(stage, val)
select 4, value from v$statname join v$sesstat using(statistic#)
where sid=sys_context('userenv','sid') and name='redo size';

結果:

select * 
from( select decode(stage,1,'heap noappend',
                          2,'heap append',
                          3,'gtt noappend',
                          4,'gtt append') as operation, 
             val-lag(val) over(order by stage) as redo 
      from gtt_results)
where redo is not null;

OPERATION     REDO                   
------------- ---------------------- 
heap noappend 606932                 
heap append   690768                 
gtt noappend  41488                  
gtt append    256                   

もちろんあなたは正しいです。私は彼らのテストでそれを捕らえるべきだった。やってみます。
リーリフェル

6

良い質問。私はしばらくの間、MVとそのインデックスをNOLOGGINGにすることで、この問題を「解決」しました。私の状況には意味がありませんでした-とにかくビューを完全に更新していましたが、なぜやり直す必要があるのですか?


1
ATOMIC_REFRESH = false必要になる場合があります(10g以上の場合)。スタンバイデータベースまたはアーカイブログを使用したリカバリにどのような影響があるかわかりませんか?
ジャックはtopanswers.xyzを試してみる11

これを実行したデータベースでロジカルスタンバイとフィジカルスタンバイを実行しています。そこに問題はありません。DBコピーの作成で問題が発生しました。メモを確認する必要がありますが、ログが記録されていないテーブルがあるテーブルスペースでリカバリを実行するとエラーが発生する場合がありました。このような問題を回避するために、ログを記録しないテーブル/インデックス用に予約されたテーブルスペースを作成するための推奨事項を読みました。私はそれを解決する方法を理解しました。
DCookie

@ジャック、私は非アトミックリフレッシュを使用しなければならなかったと思います。
DCookie

うーん、標準のマテリアライズドビューを使用する場合、アトミックな更新を行う必要があるため、これは私にとっては機能しません。他の誰かが便利だと思うかもしれないので、それでも良い答えです。
リーリフェル

なぜアトミックな更新が必要なのですか?私が理解しているように、falseに設定すると、FULLリフレッシュにのみ影響します。このasktom記事を参照してください。asktom.oracle.com/pls/apex/...
DCookie
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.