Begrenzen Sie das Wiederherstellen für die vollständige Aktualisierung der materialisierten Ansicht oder das manuelle Äquivalent


10

Mithilfe eines MV-Protokolls ( Materialized View ) kann ein MV eine schnelle Aktualisierung durchführen, bei der nur die geänderten Daten geändert werden. Verschiedene Bedingungen verhindern jedoch, dass das MV das Protokoll verwendet, und erfordern daher eine vollständige Aktualisierung. Oracle implementierte eine vollständige atomare Aktualisierung als Löschen und Einfügen jedes Datensatzes. Dies geschieht auch dann, wenn letztendlich keine Änderungen an den Daten vorgenommen wurden.

Gibt es eine Möglichkeit, diese Replikation im Hinblick auf die Redo-Generierung intelligent zu machen ? Bei einem MERGE gefolgt von einem DELETE muss die Quelle zweimal abgefragt werden. Wäre es wert, die Daten in großen Mengen zu sammeln, um eine BULK MERGE und DELETE durchzuführen? 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 des Wiederherstellens verwenden, verwenden sie immer noch zu viel.


Können Sie den gtt-Code posten? gtt's generieren Redo nicht direkt, aber sie generieren Undo - und Undo generiert Redo. insertOps erzeugen viel weniger Rückgängig als deleteoder updateOps (fast keine in der Tat). Mehrere GTTS zu haben, um teure Operationen zu vermeiden, könnte ein guter Ansatz sein
Jack sagt, versuchen Sie es mit topanswers.xyz

@Jack Douglas psoug.org/reference/gtt.html hat eine GTT Redo Generation Demo, die eine Reduzierung des Redo zwischen einer physischen Tabelle und einer GTT für inserts um 60% zeigt . Dies entspricht genau den Ergebnissen, die ich sehe, und ist besser, aber nicht so gut, wie ich es gerne hätte.
Leigh Riffel

Diese Tests (zeilenweise und ohne appendHinweis) sind keine idealen Bedingungen für die Reduzierung von Wiederholungen. Ich habe einige Tests durchgeführt, um zu zeigen, was ich meine. Gepostet als Antwort, weil sie nicht in einen Kommentar passen
Jack sagt, versuchen Sie topanswers.xyz

Antworten:


5

Dies soll lediglich die Wiederholung der Verwendung verschiedener insertVorgänge demonstrieren, anstatt die gesamte Frage zu beantworten. Die Ergebnisse meiner 10g-Instanz sind nicht zu 100% deterministisch, aber das Gesamtbild blieb bei jedem Durchlauf gleich.

Für die Heap-Tabellen weiß ich nicht, warum die insert /*+ append */mehr Redo generiert.

Prüfstand:

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                   

Sie haben natürlich Recht. Ich hätte das bei ihren Tests feststellen sollen. Ich werde es versuchen.
Leigh Riffel

6

Gute Frage. Ich habe dieses Problem für meine Situation vor einiger Zeit "gelöst", indem ich die MVs und alle Indizes auf ihnen NOLOGGING gemacht habe. Meine Situation hatte keinen Sinn - ich habe die Ansicht trotzdem vollständig aktualisiert. Warum sollte ich sie wiederholen müssen?


1
Möglicherweise benötigen Sie auch ATOMIC_REFRESH = false (ab 10 g ). Sie sind sich nicht sicher, welche Auswirkungen dies auf eine Standby-Datenbank oder die Wiederherstellung mit Archivprotokollen hat?
Jack sagt, versuchen Sie topanswers.xyz

Ich führe einen logischen und einen physischen Standby in der Datenbank aus, mit der ich dies getan habe. Keine Probleme da. Ich bin auf ein Problem beim Erstellen von DB-Kopien gestoßen - ich muss mir meine Notizen ansehen, aber es gab einen Fehler, den ich manchmal beim Wiederherstellen eines Tabellenbereichs mit Nologging-Tabellen bekam. Ich habe Empfehlungen zum Erstellen eines Tabellenbereichs gelesen, der für nicht protokollierte Tabellen / Indizes reserviert ist, um solche Probleme zu vermeiden. Ich habe allerdings herausgefunden, wie ich es lösen kann.
DCookie

@ Jack, ich glaube, ich musste nicht atomare Aktualisierung verwenden.
DCookie

Hmmm, wenn ich eine materialisierte Standardansicht verwende, muss eine atomare Aktualisierung durchgeführt werden, damit dies für mich nicht funktioniert. Jemand anderes mag es nützlich finden, daher ist es immer noch eine gute Antwort.
Leigh Riffel

Warum braucht es eine atomare Auffrischung? Soweit ich weiß, wirkt sich das Setzen auf false nur auf eine vollständige Aktualisierung aus. Siehe diesen Asktom-Beitrag: asktom.oracle.com/pls/apex/…
DCookie
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.