2016-08-05 28 views
5

Auf Oracle 11g versuche ich eine materialisierte Ansicht mit FAST REFRESH ON COMMIT zu erstellen, die eine HAVING Klausel enthält.Materialized View schnelle Aktualisierung mit HAVING-Klausel?

Die Database Data Warehousing Guide sagt:

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.

Aber wenn ich HAVING count(*)>1 (Anmerkung: keine Unterabfrage) in den eine ansonsten materialisierte Ansicht Arbeiten, bekomme ich diesen Fehler:

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

dbms_mview.explain_mview() sagt:

REFRESH_FAST     N 
REFRESH_FAST_AFTER_INSERT  N 2011 a HAVING clause is present 

Die eigentlichen Befehle:

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 

Hinweis: Die materialisierten Ansichtsprotokolle werden erstellt (andernfalls würde nicht einmal das erste Beispiel funktionieren).

Warum funktioniert es nicht? Kennt jemand ein MV-Beispiel mit einer HAVING-Klausel? Also könnte ich wenigstens von dort anfangen (ich habe gegoogelt, aber ich habe keine gefunden).

Hinweis2: Der Grund, warum ich die HAVING möchte, ist die Anzahl der Zeilen in der Ansicht von Tausenden oder sogar Millionen auf ein paar zu reduzieren. Speicher sparen (und möglicherweise Leistung gewinnen).

PS: Exact Oracle-Datenbank-Version verwendet: 11.2.0.3.0

+0

@GordonLinoff - die Funktionalität ist dokumentiert, nicht arbeiten mit einer HAVING-Klausel ** mit einer Unterabfrage **. Die Frage macht durchaus Sinn - der OP * behauptet * er hat keine Unterabfragen in seiner MV-Definition. Ob er es tut oder nicht, ist eine andere Frage - er hat etwas anderes als seine eigentliche MV-Definition veröffentlicht - aber die Frage ergibt durchaus Sinn. – mathguy

+0

@mathguy Die Beispiele in der Frage reproduzieren das Problem und sie haben keine Unterabfragen. Ich werde die Erwähnung von "anderen" Abfrage in Frage entfernen, um Verwirrung zu vermeiden. (obwohl dann jemand sagt, dass das einfache Posted-Beispiel keinen geschäftlichen Sinn macht ...). –

+0

Nun, in der Zwischenzeit hat Gordon seine Frage/Einwände auf Ihren Posten zurückgezogen, also ist das ein strittiger Punkt. Ich habe gerade die Enterprise-Version auf einem meiner Computer installiert (ich bin ein Enthusiast, der gerade für mich selbst lernt) - Ihre Frage gibt die Motivation, heute genau das zu versuchen, was Sie beschrieben haben und es zu bestätigen. Es ist bekannt, dass manchmal sogar die Dokumentation falsch ist, behalte das im Hinterkopf. – mathguy

Antwort

2

Ja, wird die Dokumentation nicht genau zu sein scheint.

Als Workaround können Sie versuchen, verschachtelte materialisierte Ansichten zu implementieren.

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

Ja, das funktioniert, aber mein Ziel ist es, diese Zeilen nicht auf der Festplatte gespeichert zu haben. Ich werde die Frage aktualisieren, um das zu berücksichtigen. –