Begrenzen Sie die Redo für die materialisierte Ansicht vollständiger Aktualisierung oder manuelles Äquivalent
-
16-10-2019 - |
Frage
Eine materialisierte Ansicht(MV) Protokoll kann verwendet werden, damit ein MV eine schnelle Aktualisierung durchführen kann, wodurch nur die geänderten Daten verändert werden. Verschiedene Bedingungen verhindern jedoch, dass das MV das Protokoll nutzt, und erfordern daher eine vollständige Aktualisierung. Oracle implementierte eine vollständige Aktualisierung von Atoms als Löschen und Einfügen jedes Datensatzes. Dies geschieht, auch wenn es letztendlich keine Änderungen an den Daten gibt.
Gibt es eine Möglichkeit, diese Replikation intelligent zu machen? In Bezug auf die Wiederherstellung der Generierung? Eine Zusammenführung, gefolgt von einem Löschen, muss zweimal die Quelle abfragen. Wäre es sich lohnen, die Daten zu sammeln, um eine Masse zusammenzuführen und zu löschen? Gibt es einen besseren Weg?
Aktualisieren:
Ich habe die Verwendung einer globalen temporären Tabelle als Staging -Bereich untersucht. Obwohl sie weniger als die Hälfte der Wiederholung verwenden, verwenden sie immer noch viel.
Lösung
Dies soll nur die Wiederholungsverwendung verschiedener nachweisen insert
Operationen anstatt die ganze Frage zu beantworten. Die Ergebnisse in meiner 10G -Instanz sind nicht 100% deterministisch, aber das breite Bild blieb jedes Mal, wenn ich durchlief.
Für die Haufentische weiß ich nicht, warum das insert /*+ append */
mehr Wiederholung erzeugt.
Testbed:
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);
Prüfung:
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';
Ergebnis:
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
Andere Tipps
Gute Frage. Ich habe dieses Problem für meine Situation vor einiger Zeit "gelöst", indem ich die MVs und alle Indizes für sie nologging. Es gab keinen Sinn für meine Situation - ich habe trotzdem eine vollständige Erfrischung der Sicht gemacht, warum sollte ich wiederholen?