Optimierer für Oracle-Funktionen

8

Ich habe eine Abfrage wie:

%Vor%

Nehmen wir an, dass foo und boo Funktionen sind, die auch viele Selects für eine super große Tabelle ohne Indizes erzeugen (daher kostet die Ausführung viel).

Ich (als Programmierer) weiß, dass foo in 99% -Zeit mehr als 5 zurückgibt, aber boo ist 99,9% liefert NULL .
Es ist offensichtlich, dass zuerst boo berechnet werden sollte. Und wenn es NULL ist, wollen wir diese Zeile nicht in der Ergebnismenge. Also müssen wir nicht foo berechnen, weil boo bereits NULL ist.

Gibt es irgendwelche Pakete / Artikel zu diesem Thema, denn wenn ich recht mache - Orakel macht diese Art der Optimierung nicht

Das obige ist nur ein Beispiel. In meinem Fall gibt es eine Menge Funktionen (~ 50) und ich benutze sie in verschiedenen Auswahlmöglichkeiten in verschiedenen Kombinationen. Also das Umschreiben der Funktionen ist nicht wirklich und Option ist in der realen Situation eine Menge von ihnen: Ich wollte nur zeigen, dass diese Anfragen wirklich langsam sind. Ich denke nur an einen Optimierer (zusätzlich zu Orakels).

    
Flufferok 12.06.2011, 04:49
quelle

4 Antworten

7

Oracle kann diese Art von Optimierung durchführen, muss aber mit dem Löffel versorgt werden Es heißt Oracle Extensible Optimizer und Statistiken verknüpfen

Aber der einfache Weg, es in diesem Fall zu tun, ist so etwas

%Vor%

wodurch die boo-Funktion vor dem foo ausgewertet wird.

Die fortgeschrittenen Sachen wären anwendbar, wenn Sie die Kontrolle über die Abfrage nicht haben (zB mit einem BI-Tool). Ein anderer Grund ist, wenn Sie eine Gruppe von Programmierern haben, bei denen es zu übertrieben wäre, diese Art von Verständnis zu entwickeln, und es einfacher ist, ein oder zwei "Datenbank-Leute" diesen Aspekt der Dinge zu verwalten.

    
Gary Myers 12.06.2011 07:33
quelle
2

Schreiben Sie einfach die Funktion boofoo , die boo ausführt, dann foo nur, wenn boo nicht null ist.

Und um das weiter zu tun, könnten Sie einen funktionsbasierten Index für diese Tabelle / Spalte hinzufügen:

%Vor%     
Mat 12.06.2011 05:02
quelle
2

Falls Sie Oracle 11 Enterprise verwenden, Ergebnis-Cache könnte helfen. Dies würde die Ergebnisse Ihrer Funktionen nach der Ausführung zwischenspeichern und würde sie nicht erneut ausführen, außer die Daten in den zugrunde liegenden Tabellen ändern sich.

Wenn das nicht funktioniert, könnten Sie versuchen, Ihre Funktionen durch VIEW s zu diesen Tabellen zu ersetzen (vorausgesetzt, Sie rufen Ihre Funktionen von mehreren Stellen auf - andernfalls könnten Sie einfach Ihre Tabellen verbinden).

Dies würde erlauben, diese Ansichten zu verbinden, anstatt die Funktionen zu verwenden, die es dem Optimierer erlauben könnten, Ihre großen Tabellen nur einmal anstatt einmal bei jedem Aufruf Ihrer Funktionen abzufragen.

Also statt

%Vor%

Sie könnten

%Vor%

und schließe dich dem

an %Vor%     
Peter Lang 12.06.2011 07:19
quelle
1

Ich habe einmal an einem ähnlichen Problem gearbeitet. In meinem Fall hatte ich nur eine Funktion, aber sie war eine schlechte: Die Anwendung war für die Namensanpassung und die Funktion gab eine Bewertung zurück, die die Ähnlichkeit zwischen dem Wert einer Zeile und der Benutzereingabe angibt. Einige Namen waren sehr gebräuchlich oder entsprachen vielen verschiedenen Varianten und brachten so Tausende von Zeilen zurück, andere würden eine Handvoll oder gar nicht zurückgeben. Die Tabelle war riesig und es gab keinen Spielraum für die Indexierung, da wir nicht alle möglichen Benutzereingaben zuordnen konnten.

Es gibt eine Reihe von alternativen Mechanismen zur Optimierung neben Indizes.

  1. Parallele Abfrage. Eine Brute-Force-Lösung, die gut funktioniert, wenn Ihr Datenbankserver über viele CPUs verfügt und Sie nicht viele Benutzer haben, die die Tabelle gleichzeitig abfragen möchten. Benötigt Enterprise Edition-Lizenz.
  2. Partitionierung. Wenn Sie andere Kriterien zum Filtern Ihrer Abfrage (Erstellungsdatum oder etwas) haben, können Sie möglicherweise Partitionsbereinigung anwenden, um den Bereich der Abfrage zu reduzieren. Die Partitionierung ist kein automatischer Leistungsgewinn: Sie ist in erster Linie eine Verwaltungsoption und kann die Leistung von Abfragen beeinträchtigen, die dem Partitionsschlüssel entgegenstehen. Erfordert die Enterprise Edition-Lizenz und die Partitionierungsoption, also teuer .
  3. Server Result Set Caching. In 11g können wir die Ergebnisse der Abfrage / Unterabfrage oder einer Funktion im Speicher ablegen; Wir bezahlen die Kosten für die einmalige Ausführung und alle nachfolgenden Abfragen erhalten das Ergebnis sofort zurück. Dies ist gut für deterministische Funktionen und langsam wechselnde Tabellen. Erfahren Sie mehr . Es handelt mit Gedächtnis für Leistung. Benötigt 11g und Enterprise Edition-Lizenz.
  4. Materialisierte Sichten. Wir können MViews verwenden, um die Ergebnisse bestimmter Abfragen vorzuberechnen, und das Optimierungsprogramm verwendet sie automatisch über die QUERY REWRITE-Funktionalität. Auch dies funktioniert am besten mit langsam wechselnden Tischen. Es handelt sich um Speicherplatz für die Leistung. Benötigt Enterprise Edition-Lizenz.
  5. Tokenizing Einige Ihrer Werte können gemeinsame Elemente haben, die sich auf den von der Funktion zurückgegebenen Wert beziehen. Zum Beispiel wird ein Wert, der mit 'Z' beginnt, niemals einen FOO() -Zielwert größer als 4 haben. Sie können diese Token entweder in separaten Tabellen, die Sie in Joins verwenden, oder als Spalten (in 11g als virtuelle Spalten) extrahieren. welche Sie indexieren können. Sie müssen diese Token-Filter möglicherweise dynamisch zur Abfrage hinzufügen. Offensichtlich funktioniert das nur für bestimmte Arten von Daten. Verfügbar in allen Editionen.
  6. Andere Spalten indizieren . Die Partitionierung eines armen Mannes, aber wenn Sie andere Spalten haben, die in der Abfrage verwendet werden, überlegen Sie, ob einige davon verwendet werden können, um die Ergebnismenge einzuschränken, bevor Sie Ihre Funktionen anwenden. Verfügbar in allen Editionen.
  7. Funktionsbasierte Indizes. Ich weiß, dass Sie diese Option bereits ausgeschlossen haben, aber Sie sollten darüber nachdenken. Sie müssen keine Indizes für jede Funktion erstellen. In diesem Beispiel filtert BOO() die meisten Zeilen und FOO() kaum. Somit wäre ein Index für BOO() sehr optimal und ein Index für FOO() schlechter als nutzlos. Sehen Sie sich Ihre Funktionen an: Stellen Sie fest, welche sehr selektiv sind und am häufigsten verwendet werden, und erstellen Sie funktionsbasierte Indizes für sie. Verfügbar in allen Editionen.

Wie Sie sehen können, benötigen viele dieser Optimierungen die Enterprise Edition. Nun, Oracle möchte, dass Sie für die teurere Lizenz einspringen, deshalb beschränken sie die coolen Funktionen. Die in der Standard Edition verfügbaren Optimierungen erfordern mehr Aufwand von uns.

Wie habe ich mein Problem gelöst? Nun, ich war auf 9i, also war Result Set Caching für mich nicht verfügbar, aber das war das, was ich wirklich wollte. Leider hatte ich viel zu viele gleichzeitige Benutzer für die parallele Abfrage möglich. Meine endgültige Lösung war eine Mischung aus Tokenisierungs- und komplizierten Indexierungsstrukturen.

    
APC 12.06.2011 07:47
quelle

Tags und Links