View in Oracle auf lang dauernde Selectabfrage?

Hallo,

Eine verschachtelte Select-Abfrage dauert etwa eine halbe Stunde.

Wenn man in Oracle dazu ein View anlegt,
wird dann das View automatisch aktualisiert wenn sich die Basistabellen ändern?

Wenn automatisch aktualisiert wird, in welchem Zeitraum passiert das?

Danke

Hallo,

Eine verschachtelte Select-Abfrage dauert etwa eine halbe
Stunde.

Das ist zu lange.
Oder zählst Du die Datensätze in Mrd.

Wenn man in Oracle dazu ein View anlegt,
wird dann das View automatisch aktualisiert wenn sich die
Basistabellen ändern?

Ja, das Selct im View ist ein vorkompiliertes Statement, das zur Laufzeit ausgeführt wird. Ich glaube kaum, dass ein View die Performance verbessert.

Ein Materialized View dagegen speichert die Ergebnisse und wird ebenfalls immer aktualisiert, wenn sich die Tabellen ändern.

Wenn automatisch aktualisiert wird, in welchem Zeitraum
passiert das?

siehe oben.

Danke

Dein Problem ist nicht View oder nicht. Dein Statement ist schlecht optimiert.

  1. Analysiere Deine Tabellen. (Vielleicht reicht das schon)
    ANALYZE TABLE xxx COMPUTE STATISTICS FOR TABLE
    Besser ist noch das AnalysePaket drüberlaufen zu lassen.

  2. Schau Dir die WHERE Bedingung an und leg INDEXE entlang dem Abfragepfad an.
    CREATE INDEX xxx ON tab(spaltex, spaltey…);
    Wenn es nichts hilft, Index wieder löschen
    DROP INDEX xxx;
    Notfalls:
    Viele Einzelindexe über jedes Attribut im WHERE anlegen.

Könnte 3 Größenordnungen bringen. Vielleicht mehr.

Gruß

Peter

Eine verschachtelte Select-Abfrage dauert etwa eine halbe
Stunde.

Das ist zu lange.
Oder zählst Du die Datensätze in Mrd.

–> Was ist zu lange ?

–> Kannst du ein Beispiel posten, mit allen Create Table Statements und der View, so dass man sich die Sache ansehen kann ? Auch die genaue Version der DB und die Anzahl der Datensätze ist notwendig. Ansonsten sind nur sehr allgemeine Aussagen machbar, und dass hilft dir nicht weiter, denke ich

Ein Materialized View dagegen speichert die Ergebnisse und
wird ebenfalls immer aktualisiert, wenn sich die Tabellen
ändern.

–> Funktioniert allerdings bei komplexen Views nicht (FastRefresh)

Dein Problem ist nicht View oder nicht. Dein Statement ist
schlecht optimiert.

  1. Analysiere Deine Tabellen. (Vielleicht reicht das schon)
    ANALYZE TABLE xxx COMPUTE STATISTICS FOR TABLE
    Besser ist noch das AnalysePaket drüberlaufen zu lassen.

  2. Schau Dir die WHERE Bedingung an und leg INDEXE entlang dem
    Abfragepfad an.
    CREATE INDEX xxx ON tab(spaltex, spaltey…);
    Wenn es nichts hilft, Index wieder löschen
    DROP INDEX xxx;

Notfalls:
Viele Einzelindexe über jedes Attribut im WHERE anlegen.

–> Besser wäre einmal die Statemets zu tracen und mittels TKPROF die Sache genauer zu analysieren. Einfach Indexe auf Verdacht rein- und rausschmeissen führt eher zu zufälligen Resultaten.

Hallo,

falls du Peters Weg folgst, ändere die Reihenfolge. Erst Index, dann Analyse. Und es ist wirklich sehr entscheiden zu wissen, welche Version du da im Einsatz hast. Je neuer, desto besser helfen im Allgemeinen diese Statistiken aus dem Analysevorgang.

Viel Glück,
Guido

Das ist zu lange.
Oder zählst Du die Datensätze in Mrd.

Ich mache mal ein Beispiel. Es gibt 2 Tabellen. In der einen sind Autos, Farbe und PS. In der anderen sind PS und Hubraum.

Nun sollen in die neu erzeugte View nur die Autos mit einem bestimmten Hubraum eingetragen werden.

Wie macht man das?

Ich habe es so gelöst:

Select Autos, Farbe, PS from autodb where ps in (select ps from Motor where hubraum = 3 Liter)

Durch solche Verschachtelungen wird das eben bei größeren Datenbanken eine längere Abfrage.
Was kann man da machen, wenn man die Basistabellen nicht großartig ändern möchte, da sie in einem System mit entsprechender Software arbeiten?

Wenn man in Oracle dazu ein View anlegt,
wird dann das View automatisch aktualisiert wenn sich die
Basistabellen ändern?

Ja, das Selct im View ist ein vorkompiliertes Statement, das
zur Laufzeit ausgeführt wird. Ich glaube kaum, dass ein View
die Performance verbessert.

Ein Materialized View dagegen speichert die Ergebnisse und
wird ebenfalls immer aktualisiert, wenn sich die Tabellen
ändern.

Ich glaube meine Frage war falsch gestellt. Wenn ich jetzt eine View anlege, und dann in 1 Monat etwas aus dieser View selektiere, wird dann die View in dem Moment neu berechnet oder werden mir die alten ungültigen Datensätze angezeigt?

  1. Schau Dir die WHERE Bedingung an und leg INDEXE entlang dem
    Abfragepfad an.
    CREATE INDEX xxx ON tab(spaltex, spaltey…);
    Wenn es nichts hilft, Index wieder löschen
    DROP INDEX xxx;
    Notfalls:
    Viele Einzelindexe über jedes Attribut im WHERE anlegen.

Könnte 3 Größenordnungen bringen. Vielleicht mehr.

Da weiss ich nicht genau wie vorgehen…

Danke

Hallo,

also wo fangen wir an:

  1. Dein Datenmodell ist falsch (nicht einfach nur schlecht)

Tabellen besitzen einen Schlüssel. Das ist ein Attribut (oder mehrere), die eine Zeile genau auffindbar machen.

Tabellen werden verknüpft, indem man auf diese Schlüssel referenziert.

Auto könnte der Schlüssel der einen Tabelle sein, PS aber kaum der der anderen (obwohl du PS so behandelst). Es gibt sicherlich mehrere Motoren gleicher Leistung mit unterschiedlichem Hubraum.

Besser:
Auto:{[autoid, marke, farbe, motorid]}
Motor:{[motorid, leistung, hubraum]}

CREATE TABLE Motor (
motorid INTEGER NOT NULL,
leistung DECIMAL(16,6),
hubraum DECIMAL(16,6),
CONSTRAINT pk_motor PRIMARY KEY (motorid)
);
CREATE TABLE Auto (
autoid INTEGER NOT NULL,
marke VARCHAR(30),
farbe VARCHAR(30),
motorid INTEGER,
CONSTRAINT pk_auto PRIMARY KEY (autoid),
CONSTRAINT fk1_auto FOREIGN KEY (motorid) REFERENCES Motor (motorid)
);

SELECT *
FROM Auto a, Motor m
WHERE a.motorid = m.motorid
AND m.hubraum > 3.0;

Bei Deinem Modell sieht das so aus:
SELECT *
FROM Auto a, Motor m
WHERE a.PS = m.PS
AND m.hubraum = 3.0;

Gruß

Peter

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

1 Like

Hallo und Danke,

endlich mal eine Antwort, die verständlich und umsetzbar ist.
Dafür gibts einen Stern.
Habe das Select so angepasst, funktioniert auch. Allerdings habe ich keine Indizes erstellt, denn ich weiss nicht ob das Nebenwirkungen hätte.
Jetzt soll es einen Benutzer geben, der nur auf diese Views Zugriff haben darf.
Das ist auch kein Problem, nur kann der Benutzer gespeicherte Prozeduren sehen. Wie entfernt man das?

SELECT *
FROM Auto a, Motor m
WHERE a.motorid = m.motorid
AND m.hubraum > 3.0;

Bei Deinem Modell sieht das so aus:
SELECT *
FROM Auto a, Motor m
WHERE a.PS = m.PS
AND m.hubraum = 3.0;

Gruß

Peter

Das ist zu lange.
Oder zählst Du die Datensätze in Mrd.

Ich mache mal ein Beispiel. Es gibt 2 Tabellen. In der einen
sind Autos, Farbe und PS. In der anderen sind PS und Hubraum.

Nun sollen in die neu erzeugte View nur die Autos mit einem
bestimmten Hubraum eingetragen werden.

Wie macht man das?

Ich habe es so gelöst:

Select Autos, Farbe, PS from autodb where ps in (select ps
from Motor where hubraum = 3 Liter)

Durch solche Verschachtelungen wird das eben bei größeren
Datenbanken eine längere Abfrage.
Was kann man da machen, wenn man die Basistabellen nicht
großartig ändern möchte, da sie in einem System mit
entsprechender Software arbeiten?

Wenn man in Oracle dazu ein View anlegt,
wird dann das View automatisch aktualisiert wenn sich die
Basistabellen ändern?

Ja, das Selct im View ist ein vorkompiliertes Statement, das
zur Laufzeit ausgeführt wird. Ich glaube kaum, dass ein View
die Performance verbessert.

Ein Materialized View dagegen speichert die Ergebnisse und
wird ebenfalls immer aktualisiert, wenn sich die Tabellen
ändern.

Ich glaube meine Frage war falsch gestellt. Wenn ich jetzt
eine View anlege, und dann in 1 Monat etwas aus dieser View
selektiere, wird dann die View in dem Moment neu berechnet
oder werden mir die alten ungültigen Datensätze angezeigt?

  1. Schau Dir die WHERE Bedingung an und leg INDEXE entlang dem
    Abfragepfad an.
    CREATE INDEX xxx ON tab(spaltex, spaltey…);
    Wenn es nichts hilft, Index wieder löschen
    DROP INDEX xxx;
    Notfalls:
    Viele Einzelindexe über jedes Attribut im WHERE anlegen.

Könnte 3 Größenordnungen bringen. Vielleicht mehr.

Da weiss ich nicht genau wie vorgehen…

Danke

Hallo und Danke,

endlich mal eine Antwort, die verständlich und umsetzbar ist.
Dafür gibts einen Stern.
Habe das Select so angepasst, funktioniert auch. Allerdings
habe ich keine Indizes erstellt, denn ich weiss nicht ob das
Nebenwirkungen hätte.
Jetzt soll es einen Benutzer geben, der nur auf diese Views
Zugriff haben darf.
Das ist auch kein Problem, nur kann der Benutzer gespeicherte
Prozeduren sehen. Wie entfernt man das?

Hallo,

CREATE USER xxx IDENTIFIED BY userpwd;
GRANT CONNECT TO xxx;
GRANT INSERT, UPDATE, DELETE, SELECT ON schema.tabelle TO xxx;
das hier für alle tabellen, die er sehen und bearbeiten darf. (Natürlich nur das, was er darf)
GRANT EXECUTE ON schema.prozedur TO xxx;
ebenso.

Das CREATE USER musst Du als Administrator machen (SYSTEM?),
die GRANTs kannst Du auch vom Schema des Besitzers aus machen.

Nun die „schöne“ Variante:

Nimm die Oracle Enterprise Manager Konsole (Start -> Programme -> Oracle - OraHome92 -> Enterprise Manager Console.
Standalone starten
Lokale DB sollte schon da sein, oder bei Datenbank hinzufügen unten den RadioButton anklicken.
DB öffnen.
Als Administrator einloggen.
Nun gehts alles klickiklacki selbsterklärend weiter.
Wer die Konsole öffnen will braucht das Systemprivileg: SELECT ANY DICTIONARY bei der 9i.

Gruß

Peter

1 Like

Hallo und noch ein Sternchen,

CREATE USER xxx IDENTIFIED BY userpwd;
GRANT CONNECT TO xxx;
GRANT INSERT, UPDATE, DELETE, SELECT ON schema.tabelle TO xxx;

Das ganze habe ich schon gemacht, und nur das nötige vergeben, trotzdem können ein paar Systemtabellen usw. angesehen werden, ohne dass ich dies erlaubt hätte.

Hallo,

es gibt einige Systemtabellen, auf die MUSS ein User zugreifen (lesen) können. Das ist ganz normal. Wenn sich Dein User z.B. die ALL_TABLES anschauen will, wird er da nicht viel drin sehen. Nur die für ihn freigegebenen Tabellen.

Du kannst übrigens auch einschränken wann, wielange, wer, von welcher IP, möglicherweise auch MAC-Adresse, Terminal, und mit welchem Programm sich ein User einloggen kann. Das Stichwort dazu lautet TRIGGER ON LOGON. Du findest in Google einige sehr gute Seiten dazu.

Gruß

Peter

Hi!

Hallo,

Du kannst übrigens auch einschränken wann, wielange, wer, von
welcher IP, möglicherweise auch MAC-Adresse, Terminal, und mit
welchem Programm sich ein User einloggen kann. Das Stichwort
dazu lautet TRIGGER ON LOGON. Du findest in Google einige sehr
gute Seiten dazu.

Teilweise funktioniert das auch mittels Profiles, Rollen, etc. innerhalb der Datenbank selber - da erspart man sich einiges an Triggern …

Grüße,
Tomh