2009-09-23 11 views
10

Hat jemand bei der Verwendung von Oracle-Analysefunktionen eine langsame Leistung festgestellt? Die oracle analytic-Funktion lead() wurde verwendet, um ein neues Feld in der Tabelle zu generieren. Grundsätzlich würde der Feldwert der vorherigen Zeile als Wert für das neue Feld der aktuellen Zeile verwendet. Der EXPLAIN-Plan zeigt an, dass in der Tabelle, in der die Oracle-Analysefunktion verwendet wurde, ein vollständiger Tabellenscan durchgeführt wird.Sind Oracle Analytic Functions teuer?

Um die Kosten dieser vollständigen Tabellenscan zu vermeiden, kann ich ein konkretes Feld mit der vorherigen Reihe Wert unter Verwendung eines nach dem insert/update-Trigger bevölkern nur manuell müssen

hat beschlossen, niemandem ein Orakel analytische Funktion zu verwenden, wegen seiner hohen Kosten? Sollten orakelanalytische Funktionen selten verwendet werden?

+0

Warum zeigen Sie uns Ihren Code nicht? Es ist sehr schwierig, ohne sie einen guten Rat zu geben. Ich verstehe nicht, warum die analytische Funktion einen vollständigen Tabellenscan durchführen muss. Können Sie nicht zuerst ID mit einer Where-Klausel filtern? – tuinstoel

Antwort

2

Dies hängt davon ab, wie Ihre Tabelle indiziert ist und welche Funktionen Sie verwenden.

ROW_NUMBER(), zum Beispiel, scheint weniger effizient als ROWNUM, auch wenn die Indizes verwendet werden. Lesen Sie diesen Artikel in meinem Blog zum Performancevergleich:

Oracle ‚s Optimierer über Fensterfunktionen kennt und einige Tricks, wie STOPKEY und PUSHED RANK verwenden können, die sie effizienter zu machen.

Der EXPLAIN-Plan gibt an, dass in der Tabelle, in der die Oracle-Analysefunktion verwendet wurde, ein vollständiger Tabellenscan durchgeführt wird.

Die Tabelle Scan selbst ist nicht schlecht. Dies kann in der Tat optimal sein, wenn die TABLE ACCESS zum Abrufen der im Index fehlenden Werte teurer ist als das Filtern und Sortieren.

Normalerweise, wenn Ihre Tabelle indiziert ist, die Abfrage WHERE und ORDER BY Klauseln ermöglichen diesen Index mit für die Bestellung und Optimierer berücksichtigt dieser Index lohnt sich der Einsatz, die WINDOW BUFFER Methode für LAG und LEAD Funktionen verwendet wird.

Die Engine behält nur einen Laufpuffer von 2 Zeilen (oder mehr, abhängig vom Wert des Offsets) und gibt die Werte aus der ersten und der zweiten Zeile zurück.

Der Optimierer kann jedoch davon ausgehen, dass sich der Index überhaupt nicht lohnt.

In diesem Fall wird WINDOW SORT verwendet: dasselbe, aber die Sortierung erfolgt im Speicher oder im temporären Tablespace.

6

die analytischen Funktionen sind nicht ohne Kosten: Sie müssen Daten für Zwischenergebnisse speichern (laufende Summen, Fensterfunktionen ...), die Speicher benötigen und sie benötigen auch etwas Rechenleistung. Einige Funktionen müssen in die letzte Zeile einer Ergebnismenge gelangen, um ein Ergebnis zurückgeben zu können (zB MIN/MAX). Die meisten Funktionen haben auch eine implizite SORT-Operation.

Sie sind daher nicht frei in Bezug auf Ressourcen, aber sie sind SET-Operationen und die meiste Zeit sind sie daher viel effizienter als das Schreiben von benutzerdefinierten Zeile-für-Zeile-PLSQL-Prozedur oder traditionelle SQL.

Sie müssen vergleichen und Benchmark in Ihrem speziellen Fall, aber wenn Sie sie mit Bedacht verwenden, werden Sie sehen, dass sie ein leistungsstarkes Leistungstool, kein Hindernis sind.

3

Einige Details hierzu finden Sie im Blog here von Jonathan Lewis.

Eigentlich sollte die Frage sein, sind sie mehr oder weniger teuer als die Alternative, und das wird auf die besondere Situation kommen. In einigen Fällen ziehen Sie es möglicherweise vor, die Daten auf einen App-Server zu ziehen und dort zu verarbeiten, nur weil es in der Regel billiger/einfacher ist, zusätzliche Hardware auf dieser Ebene zu haben.

Aber die Wahl zwischen SQL und Hinzufügen von PL/SQL-Verarbeitung gegeben, würde ich in der Regel die SQL verwenden.

1

Natürlich haben sie eine Kosten und Sie müssen entscheiden, ob Sie es bezahlen können oder nicht.

In meinem Fall erstellte ich eine gespeicherte Prozedur, die eine Tabelle iteriert und einige Daten mithilfe der Oracle-Funktion lead() berechnet und die Ergebnisse in einer anderen Tabelle speichert. Schließlich verwende ich diese spätere Tabelle in meiner App und aktualisiere die erste Tabelle (die die gespeicherte Prozedur ausführt) einmal pro Woche, da sich diese Daten nicht häufig ändern.

Für mich war dies die beste Lösung.