Ogranicz ponawianie, aby zmaterializować pełne odświeżenie widoku lub odpowiednik ręczny

10

Można użyć dziennika widoku zmaterializowanego (MV), aby umożliwić MV szybkie odświeżenie, które modyfikuje tylko zmienione dane. Jednak różne warunki uniemożliwiają MV korzystanie z dziennika i dlatego wymagają pełnego odświeżenia. Oracle zaimplementowało całkowite odświeżenie atomowe jako usunięcie i wstawienie każdego rekordu. Robi to, nawet jeśli ostatecznie nie ma żadnych zmian w danych.

Czy istnieje sposób na uczynienie tej replikacji inteligentną w odniesieniu do generowania powtórzeń ? MERGE, a następnie DELETE, wymaga dwukrotnego zapytania do źródła. Czy warto zbiorczo gromadzić dane, aby wykonać LICZBĄ POŁĄCZENIE i USUŃ? Czy jest lepszy sposób?

Aktualizacja:

Zbadałem, używając globalnego tymczasowego stołu jako obszaru przejściowego. Mimo że wykorzystują mniej niż połowę przeróbek, nadal używają ich za dużo.

Leigh Riffel
źródło
Czy możesz opublikować kod gtt? gtt nie generują ponawiania bezpośrednio, ale generują cofanie - i cofanie generuje ponawianie. insertoperacje generują znacznie mniej operacji cofania deletelub updateoperacji (prawie żadnych). Posiadanie wielu GTT, aby uniknąć kosztownych operacji, może być dobrym podejściem
Jack mówi, spróbuj wypróbować topanswers.xyz
@Jack Douglas psoug.org/reference/gtt.html ma wersję demonstracyjną generowania powtórzeń GTT pokazującą 60% zmniejszenie powtórzeń między tabelą fizyczną a GTT dla inserts. Jest to ściśle zgodne z wynikami, które widzę i jest lepsze, ale nie tak dobre, jak bym chciał.
Leigh Riffel
Te testy (rząd po rzędzie i brak appendpodpowiedzi) nie są idealnymi warunkami do ograniczenia powtarzania - uruchomiłem kilka testów, aby pokazać, co mam na myśli. Wysłany jako odpowiedź, ponieważ nie zmieści się w komentarzu
Jack mówi, spróbuj wypróbować topanswers.xyz

Odpowiedzi:

5

Ma to na celu jedynie wykazanie ponownego użycia różnych insertoperacji zamiast odpowiedzi na całe pytanie. Wyniki dla mojej instancji 10g nie są w 100% deterministyczne, ale szeroki obraz pozostał taki sam za każdym razem, gdy przechodziłem.

W przypadku tabel sterty nie wiem, dlaczego insert /*+ append */wygenerowano więcej powtórzeń.

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);

test:

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';

wynik:

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                   
Jack mówi, że spróbuj topanswers.xyz
źródło
Oczywiście masz rację. Powinienem był to złapać podczas ich testów. Dam temu szansę.
Leigh Riffel,
6

Dobre pytanie. „Rozwiązałem” ten problem dla mojej sytuacji jakiś czas temu, robiąc MV i wszelkie indeksy na nich NOLOGGING. Moja sytuacja nie miała sensu - i tak robię pełne odświeżenie widoku, dlaczego miałbym potrzebować przerobić?

DCookie
źródło
1
Możesz także potrzebować ATOMIC_REFRESH = false (na 10 g i więcej). Nie wiesz, jakie są konsekwencje dla rezerwowej bazy danych lub odzyskiwania z dzienników archiwalnych?
Jack mówi, że spróbuj topanswers.xyz
W bazie danych uruchomiłem logiczny i fizyczny tryb gotowości. Brak problemów. Wystąpił problem z tworzeniem kopii DB - musiałem spojrzeć na swoje notatki, ale wystąpił błąd, który czasami miałem do czynienia z odzyskiwaniem w obszarze tabel z tabelami nologowania. Przeczytałem zalecenia dotyczące utworzenia obszaru tabel zarezerwowanego dla tabel / indeksów, które nie są rejestrowane, aby uniknąć takich problemów. Jednak wymyśliłem, jak to rozwiązać.
DCookie
@Jack, wydaje mi się, że musiałem użyć odświeżania nieatomowego.
DCookie,
Hmmm, jeśli użyję standardowego zmaterializowanego widoku, musi on wykonać odświeżenie atomowe, więc to nie zadziała dla mnie. Ktoś inny może uznać to za przydatne, więc nadal jest to dobra odpowiedź.
Leigh Riffel,
Dlaczego potrzebuje odświeżania atomowego? Jak rozumiem, ustawienie wartości false wpływa tylko na PEŁNE odświeżenie. Zobacz ten post na asktomie: asktom.oracle.com/pls/apex/…
DCookie,