Frage

Auf einmal (aber leider weiß ich nicht, wenn „plötzlich“ war, ich weiß, es lief gut an einem gewissen Punkt in der Vergangenheit) ein meine Abfragen gestartet 7+ Sekunden statt Millisekunden nehmen auszuführen. Ich habe 1 lokale Tabelle und 3 Tabellen DB über einen Link zugegriffen werden. Die 3 entfernten Tabellen miteinander verbunden ist, und einer von ihnen ist mit meiner lokalen Tabelle verknüpft.

Die lokale Tabelle ist, wo Klausel nur wenige millis nimmt auf eigenem auszuführen, und gibt nur wenige (10 oder die 100 sind bei den meisten) Aufzeichnungen. Die 3 entfernten Tabellen haben viele Hunderttausende, vielleicht Millionen von Datensätzen zwischen ihnen, und wenn ich sie kommen in geeigneter Weise bekomme ich Dutzende oder Hunderte von Tausenden von Datensätzen.

Ich bin nur mit den entfernten Tabellen verknüpft werden, so dass ich zu jedem Datensatz in meiner lokalen Tabelle, ein paar Stücke von Daten herausziehen kann.

Was aber passiert zu sein scheint, ist, dass Oracle die Remote-Tabellen zusammen und dann meine lokale Tabelle in diesem Chaos am Ende verbindet. Dies wird immer eine schlechte Idee, vor allem der Datenmenge gegeben, die jetzt vorhanden ist, so dass ich einen /*+ LEADING(local_tab remote_tab_1) */ Hinweis auf meine Frage und es gibt nun in Millisekunden hinzugefügt.

Ich verglich die erklären, Pläne und sie sind fast identisch, außer für einen einzelnen BUFFER SORT auf einem der entfernten Tabellen.

Ich frage mich, was könnte dazu führen, Oracle dies den falschen Weg zu nähern? Ist es ein Index Problem? Was soll ich suchen?

War es hilfreich?

Lösung

Wenn Sie einen Ausführungsplan wählen, schätzt Oracle Kosten für die verschiedenen Pläne. Eine wichtige Informationen für diese Schätzung ist die Menge der Zeilen wird von einem Schritt des Ausführungsplans zurückgegeben. Oracle versucht, diejenigen unter Verwendung von ‚Statistik‘, das heißt Informationen darüber, wie viele Zeilen eine Tabelle enthält, wie viele verschiedene Werte einer Spalte enthält, zu schätzen; Wie gleichmäßig diese Werte verteilt werden.

Diese Statistiken nur, dass die Statistiken, und sie könnte falsch sein, was für Fehlurteile des Orakels Optimierer einer der wichtigsten Gründe ist.

Sammeln So neue Statistiken, wie in einem Kommentar könnte helfen, beschrieben. Werfen Sie einen Blick in die Dokumentation zu diesem dbms_stats Paket. Es gibt viele verschiedene Möglichkeiten, um das Paket zu nennen.

Andere Tipps

Ein gemeinsames Problem, das ich bin gekommen, über eine Abfrage, die viele Tabellen verknüpft, wo die eine Kette von einem Ende zum anderen schließt sich bilden, z.

SELECT *
FROM   tableA, tableB, tableC, tableD, tableE
WHERE  tableA.ID0 = :bind1
AND    tableA.ID1 = tableB.ID1
AND    tableB.ID2 = tableC.ID2
AND    tableC.ID3 = tableD.ID3
AND    tableD.ID4 = tableE.ID4
AND    tableE.ID5 = :bind2;

Beachten Sie, wie der Optimierer wählen könnte die Abfrage von tableA (z, wenn der Index auf ID0 ist schön selektiv) oder von Tablee (wenn der Index auf tableE.ID5 ist selektiver) zu fahren.

Die Statistiken über die Tabellen könnten die Wahl zwischen diesen beiden Plänen führen auf Messers Schneide zu balancieren; ein Tag wird es funktioniert gut (von tableA fahren), am nächsten Tag neue Statistiken gesammelt und ganz plötzlich der alternative Plan von Tablee Fahren hat ein niedriger Kosten und gewählt wird.

Unter diesen Umständen einen führenden Hinweis hinzuzufügen, ist eine Art und Weise es schubsen wieder auf den ursprünglichen Plan (dh Fahrt von tableA), ohne zu viel zu Optimiser diktiert (dh es nicht zwingt, die Optimierers wählen eine bestimmte Join-Methoden).

Sie tun verteilte Abfrage-Optimierung, und das ist ein heikles Tier. Es könnte sein, dass die Statistiken Ihrer Tabelle der aktuell sind, aber jetzt ist die Tabellen auf dem Remote-System sind out-of-Whack oder verändert haben. Oder das Remote-System hinzugefügt / entfernt / modifizierte Indizes und das brach Ihren Plan. (Dies ist ein guter Grund Replikation zu berücksichtigen -., So dass Sie Indizes und Statistiken dagegen steuern können)

Das heißt, Oracle Schätzung von Kardinalität ist ein wesentlicher Faktor in Ausführungsplan. A 10053 Spurenanalyse (Jonathan Lewis' Cost-Based Oracle Fundamentals Buch hat wunderbare Beispiele von 8i bis 10.1) kann helfen, werfen Licht auf, warum Ihre Aussage ist nun gebrochen und wie die LEADING Hinweis behebt es.

Der DRIVING_SITE Hinweis könnte eine bessere Wahl sein, wenn Sie wissen, dass Sie immer die lokalen Tabellen wollen zuerst verbunden werden, bevor nach dem Remote-Standort gehen; es stellt klar Ihre Absicht, ohne den Plan den Weg wäre ein LEADING Hinweis zu fahren.

Könnte nicht relevant sein, aber ich hatte eine ähnliche Situation einmal, wo die entfernte Tabelle war von einem Einzeltisch-Ansicht ersetzt. Wenn es eine Tabelle, die verteilte Abfrage-Optimierer ‚Säge‘, dass es einen Index hatte. Wenn es eine Ansicht wurde konnte es nicht den Index mehr sehen und konnte nicht einen Plan kosten, die einen Index auf dem Remote-Objekt verwendet wird.

Das ist vor ein paar Jahren war. Ich dokumentierte meine Analyse zu der Zeit hier .

RI,

Es ist schwer, sicher über die Ursache für die Performance-Probleme zu sein, ohne die SQL zu sehen.

Wenn eine Oracle-Abfrage wurde gut vor der Durchführung, und plötzlich schlecht beginnt durchgeführt wird, ist es in der Regel zu einem von zwei Fragen im Zusammenhang:

  

A) Statistiken sind veraltet aus. Dies ist die einfachste und schnellste, was zu überprüfen, auch wenn Sie einen Reinigungs Batch-Prozess haben, kümmern es angenommen hat ... immer überprüfen.

     

B) Datenvolumen / Datenmuster zu ändern.

In Ihrem Fall eine verteilte Abfrage über mehrere Datenbanken laufen macht es 10x härter für Oracle Leistung zwischen ihnen zu verwalten. Ist es möglich, diese Tabellen in einer Datenbank, vielleicht separates Schema Besitzer in einer Datenbank zu setzen?

Hinweise sind notorisch instabil, wie Oracle unter keinen Verpflichtungen ist der Hinweis zu folgen. Wenn das Datenvolumen oder Muster, das etwas mehr ändert, kann Oracle nur den Hinweis ignorieren und tun, was denkt, es ist am besten (dh schlechteste; -.).

Wenn Sie diese Tabellen nicht alle in einer Datenbank setzen kann, dann empfehle ich Ihnen suchen Ihre Suche zu brechen in zwei Anweisungen:

  1. INSERT auf dem Unter SELECT externen Daten in der aktuellen Datenbank in einer globalen temporären Tabelle kopieren.
  2. Wählen Sie aus der globalen temporären Tabelle mit dem anderen Tabelle zu verbinden.

In Kürze erhalten Sie haben die vollständige Kontrolle über die Durchführung von Schritt 1 oben ohne auf Hinweise zurückgreifen. Dieser Ansatz skaliert der Regel gut, Sie einige Zeit dauern, die Bereitstellung der Performance-Tuning zu tun. Ich habe dieser Ansatz gesehen viele komplexe Performance-Probleme lösen.

Der Aufwand für Oracle eine neue Tabelle zu erstellen, oder einen Haufen Datensätze einfügen, ist viel kleiner als die meisten Leute erwarten. eine globale temporäre Tabelle definiert weiter reduziert, dass die Overhead.

Matthew

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top