2016-08-05 23 views
5

Na Oracle 11g próbuję utworzyć zmaterializowany widok z FAST REFRESH ON COMMIT, który zawiera klauzulę HAVING.Zmaterializowany widok szybkiego odświeżania z klauzulą ​​HAVING?

Database Data Warehousing Guide mówi:

General Restrictions on Fast Refresh

The defining query of the materialized view is restricted as follows:

  • It cannot contain a HAVING clause with a subquery.

Ale jeśli dodać HAVING count(*)>1 (uwaga: nie podzapytanie) Do inaczej zmaterializował pracę pogląd, otrzymuję ten błąd:

ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view

dbms_mview.explain_mview() mówi:

REFRESH_FAST     N 
REFRESH_FAST_AFTER_INSERT  N 2011 a HAVING clause is present 

Rzeczywiste polecenia:

SQL> create materialized view mv1 refresh fast on commit as 
    2  select UserId, count(*) from USERS group by UserId; 

Materialized view created. 

SQL> DROP MATERIALIZED VIEW mv1; 

Materialized view dropped. 

SQL> create materialized view mv1 refresh fast on commit as 
    2  select UserId, count(*) from USERS group by UserId 
    3   having count(*)>1; -- the only difference 
    having count(*)>1 
        * 
ERROR at line 5: 
ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view 

Uwaga: Utworzono logi widoku zmaterializowanego (w przeciwnym razie nie działałby nawet pierwszy przykład).

Dlaczego to nie działa? Czy ktoś zna przykład MV z klauzulą ​​HAVING? Tak więc przynajmniej mógłbym zacząć od tego (ja googled, ale nie znalazłem).

Uwaga2: Powodem, dla którego chcę HAVING jest zmniejszenie liczby wierszy w widoku z tysięcy lub nawet miliona do kilku. Aby zaoszczędzić miejsce (i ewentualnie zwiększyć wydajność).

PS: Exact wersja bazy danych Oracle używany: 11.2.0.3.0

+0

@GordonLinoff - funkcja jest udokumentowana, nie działa z klauzulą ​​HAVING ** z podzapytaniem **. Pytanie to ma sens - OP * twierdzi, że nie ma podkwerend w swojej definicji MV. Czy to robi czy nie, to kolejne pytanie - opublikował coś innego niż jego rzeczywistą definicję MV - ale to pytanie ma sens. – mathguy

+0

@mathguy Przykłady w pytaniu odwzorowują problem i nie mają żadnych podkwerend. Usuwam wzmiankę o "innej" kwerendzie, aby uniknąć nieporozumień. (choć wtedy ktoś powie, że prosty wysłany przykład nie ma sensu biznesowego ...). –

+0

Cóż, w międzyczasie Gordon wycofał swoje pytanie/sprzeciw do swojego stanowiska, więc jest to kwestia sporna. Niedawno zainstalowałem wersję Enterprise na jednym z moich komputerów (jestem entuzjastą, który uczy się tylko dla siebie) - twoje pytanie motywuje do dziś, spróbuj dokładnie tego, co opisałeś i potwierdź. Wiadomo, że czasami nawet dokumentacja jest błędna, należy o tym pamiętać. – mathguy

Odpowiedz

2

Tak, dokumentacja wydaje się nie być dokładne.

Aby obejść ten problem, spróbuj wdrożyć zagnieżdżone zmaterializowane widoki.

CREATE MATERIALIZED VIEW mv1 
REFRESH FAST ON COMMIT 
AS 
SELECT col1, 
     COUNT(col1) count_col1 
FROM test_table 
GROUP BY col1 

ALTER MATERIALIZED VIEW mv1 ADD CONSTRAINT pk_mv1 PRIMARY KEY (col1) 

CREATE MATERIALIZED VIEW LOG ON mv1 WITH PRIMARY KEY; 

CREATE MATERIALIZED VIEW MV2 
REFRESH FAST ON COMMIT AS 
SELECT col1, 
     count_col1 
FROM mv1 
WHERE count_col1 > 1 
+0

Tak, to działa, ale moim celem jest, aby w ogóle nie przechowywać tych wierszy na dysku. Zaktualizuję pytanie, aby to odzwierciedlić. –

Powiązane problemy