Materialized View - Fast refresh, odniesienie do widoku.

0

Hej,
mam problem z utworzeniem widoku zmaterializowanego, który będzie miał opcje odświeżania Fast Refresh. Logika wymaga abym miał count() użyty, aby obliczyć pewne wartości. Jak wyczytałem, widok zmaterializowany nie puszcza tego, ale można to obejść tworząc widok, który będzie używał owej funkcji. Niestety, po połączeniu widoku zmaterializowanego z widokiem, dostaje error:
An error was encountered performing the requested operation:


ORA-12004: REFRESH FAST nie może być użyte dla zmaterializowanej perspektywy 
ORA-06512: przy "SYS.DBMS_SNAPSHOT", linia 2821
ORA-06512: przy "SYS.DBMS_SNAPSHOT", linia 3058
ORA-06512: przy "SYS.DBMS_SNAPSHOT", linia 3017
ORA-06512: przy linia 1
12004. 00000 -  "REFRESH FAST cannot be used for materialized view \"%s\".\"%s\""
*Cause:    The materialized view log does not exist or cannot be used. PCT
           refresh is also not enabled on the materialized view
*Action:   Use just REFRESH, which will reinstantiate the entire table.
           If a materialized view log exists and the form of the materialized
           view allows the use of a materialized view log or PCT refresh is
           possible after a given set of changes, REFRESH FAST will
           be available starting the next time the materialized view is
           refreshed.
Vendor code 12004

Materialized View logs istnieją dla wszystkich tabel, ale nie wiem jak utworzyć je dla widoku. Tak samo nie mogę utworzyć columny ROWID dla widoku. Jak mogę naprawić owy błąd? Ewentualnie, jeśli używanie funkcji agregacyjnych jest niedozwolone dla fast refresh, jakieś ciekawe obejście ktoś może podsunąć?

0

Może na jednej z tabel "pod spodem" były robiony truncate? Może coś innego się wydarzyło. Jesteś w stanie wyprodukować minimalny przykład, który problem zreplikluje?

Oracle ma całą notkę jak to diagnozować: Diagnosing ORA-12004 Refresh Fast Cannot be Used (Doc ID 179469.1)

1

Już podaje przykład. Widok pomocniczy wygląda mniej więcej tak:

Select a.id,
greatest(b.date, sysdate) loc_date,
b.num,
(select count(w_day)
from spec_calendar
where trunc(w_day) >= b.start_day
and trunc(w_day) < b.end_date) duration
from tableA a, tableB b
where a.id = b.id
and b.num in (1,2,3)

Oraz widok zmaterializowany:

select a.id,
b.num,
greatest(b.date, sysdate) loc_date
case 
when b.num in (1,2,3)
then
c.duration
else 
b.end-b.start
end * a.value as sum_value,
a.rowid a_rowid,
b.rowid b_rowid
from tableA a, tableB b, viewC c
where a.id = b.id
and a.id = c.id(+)
and loc_date = c.loc_date(+)

Mniej więcej na takiej zasadzie to jest tworzone, gdy utworzę z widoku tabelę to śmiga wszystko super, niestety zależy mi aby to był widok, bo daje to sporo elastyczności.

0
  1. Podałeś zapytanie, ale w jaki sposób tworzysz ten widok zmaterializowany i z jakimi parametrami? Na pierwszy rzut oka problemem jest "greatest(b.date, sysdate) loc_date". Spróbuj wyciąć to sysdate, np. zastąp do testów jakąś konkretną wartością i zobacz czy "fast refresh" działa.
  2. Jaki problem rozwiązuje ten widok zmaterializowany?
0
  1. Zobaczę, czyli problemem może być przyrównanie do greatest? Jak utworzyłem z zapytania widoku tabele, to śmiga bez zarzutu, ale zależy mi aby to był jednak widok. Dodatkowo, count() jest zrobiony z tabeli, która nie jest joinowana, czy to może być problemem?
  2. Widok przedstawia dane firmowe, które są odświeżane co 5 minut fast refreshem.
0

Na logikę:

  • "fast refresh" operuje na logach zmian (od ostatniego odświeżenia) w tabelach źródłowych, ale te nie muszę się przecież zmieniać
  • sysdate się zmienia, więc wyliczone w widoku zmaterializowanym greatest() może nie być aktualne, mimo że tabele źródłowe nie musiały ulec zmianie
    Jak to wg Ciebie miałoby działać?

Dlaczego widok zmaterializowany, a nie zwykły widok? Masz do przesłania gigabajty danych po db linkach?

0
yarel napisał(a):

Na logikę:

  • "fast refresh" operuje na logach zmian (od ostatniego odświeżenia) w tabelach źródłowych, ale te nie muszę się przecież zmieniać
  • sysdate się zmienia, więc wyliczone w widoku zmaterializowanym greatest() może nie być aktualne, mimo że tabele źródłowe nie musiały ulec zmianie
    Jak to wg Ciebie miałoby działać?

Dlaczego widok zmaterializowany, a nie zwykły widok? Masz do przesłania gigabajty danych po db linkach?

Niestety zależy nam na szybkości odczytu danych, a query samo w sobie trwa 20 minut, więc zmusza to do widoku zmaterializowanego.

0

Nie mam pełnej wiedzy o danych, ale te 20 minut wygląda mega podejrzanie i wyszedłbym od planu zapytania i poprawy tegoż planu. Widoki zmaterializowany w Twoim przypadku może nie być właściwym rozwiązaniem optymalizacji czasu wykonania zapytania...

  • Ile masz wierszy w tabelkach: A,B, SPEC_CALENDAR i ile miejsca zajmują te dane?
  • Jak obecnie wygląda plan wykonania dla takiego zapytania?
  • Jaki powinien być czas wykonania zapytania?
  • Ile równoległych wykonań tego zapytania?

1 użytkowników online, w tym zalogowanych: 0, gości: 1