web-dev-qa-db-ja.com

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

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

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

更新:

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

10
Leigh Riffel

これは、質問全体に答えるのではなく、さまざまなinsert操作のやり直しの使い方を示すことだけを目的としています。私の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                   

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

6
DCookie