pl/sql-Prozedur... wo kommt der Zeitpunkt der Ausführung gehen?
Ich bin derzeit auf der Verfolgung eines performance-Leck in einer gespeicherten Prozedur.
Mit einem timestamp setzen sich direkt nach der ersten "begin" - und einer rechts vor dem endgültigen "Ende" (ich mache einen commit vor) sagt, der Vorgang dauert abt. 10 Sekunden zu beenden.
Allerdings habe ich zu warten, nur 2 Minuten+ für Sie zu Ende.
Kann mir jemand sagen, wo der rest der Zeit geht? Ich bin mit Oracle-SQL-dev, aber Es scheint nicht zu sein, idleing für den rest der Zeit, das Verfahren scheint die Sperre für die betreffende Tabelle 🙁
Vielen Dank im Voraus für die Aufklärung....
EDIT: nochmals vielen Dank für euren input 🙂
hier ist der vereinfachte code für die Prozedur, je nach der Anzahl der Elemente, die verarbeitet werden, 1. Abschnitt derzeit dauert abt. 10 bis 40 Sekunden, die 2. Sektion ein paar millisecs. aber das Verfahren dauert 2 bis 8 Minuten zu laufen.
auch die Tabelle mit den Daten zu löschen scheinen gesperrt zu werden etwas länger als nötig, wodurch Einsätze verschoben werden.
der Start als geplanter job macht keinen Unterschied, btw, dasselbe Verhalten.
create or replace
procedure MY_PROCEDURE is
start_procedure number;
start_delete number;
end_procedure number;
begin
start_procedure :=dbms_utility.get_time;
begin
-- stripped: doing some selects/updates here
end;
commit;
start_delete :=dbms_utility.get_time ;
begin
-- stripped: cleanig up some other data here
end;
commit;
end_procedure :=dbms_utility.get_time ;
dbms_output.put_line('procedure took: '||to_char((end_procedure- start_procedure)/1000));
dbms_output.put_line('updates took: '||to_char((start_delete- start_procedure)/1000));
dbms_output.put_line('delete took: '||to_char((end_procedure-start_delete)/1000));
end;
guter Vorschlag - habe es gerade ausprobiert. es dauert so lange, wie mit der sqldev
Könnten Sie den text für die Prozedur (mit dem Mut, zwischen den Zeitstempel prüft entfernt), und ein Beispiel des Codes, die Sie verwenden, um es zu testen?
vielen Dank für Ihren Kommentar. soeben das vereinfachte code
InformationsquelleAutor PeterP | 2009-06-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie ersetzen diese Aufrufe zu dbms_utility.get_time durch Nachrichten wie:
und rufen Sie dann die Prozedur wie dieses:
dann der Ort, wo die fehlende Zeit kommt wird sich zeigen.
to_char(systimestamp, 'HH24:MI:SS.FF3')
oder eine höhereFF
WertInformationsquelleAutor Tony Andrews
Ich denke, Sie brauchen, um eine Teilung durch 100, nicht 1000(dbms_utility.get_time gibt in centiseconds). Das sollten Sie sich 100 Sekunden, was in etwa 2 Minuten.
Allerdings, wenn Sie daran interessiert, herauszufinden, wo die 2 Minuten Ausführung die Zeit ging, und je nach der Komplexität des Verfahrens, möchten Sie vielleicht, um entweder:
Profiler kann besser sein, wenn Sie eine Menge von verketteten PL/SQL-procedure-calls. Die statspack Bericht wird besser sein, wenn Sie haben meist sql-Anweisungen in der gespeicherten Prozedur.
Hier ist, was der Profiler-Ausgabe sieht so aus:
Sind Sie vertraut mit, wie Sie sammeln ein statspack Bericht? Das ist wahrscheinlich der einfachste Weg, um begonnen zu erhalten, wie Sie einen neuen Benutzer. Es wird Ihnen sagen, welche Aussagen sind verantwortlich für die Zeit-und was macht Sie langsam.
Im Grunde, ich bin sehr neu auf all dies - das ist, warum ich dachte, die Ausgabe der Zeitstempel wäre der einfachste Weg, um das problem zu finden... ich werde haben Sie einen Blick auf das statspack Sache... vielen Dank
InformationsquelleAutor Plasmer
Ich bin nicht vertraut mit pl/sql, aber gibt es eine Möglichkeit, um zu pausieren oder unterbrechen, während es läuft?
Die chance, dass Sie traf ihn, während er die verschwenderisch ist gleich dem Prozent der Zeit, es zu verschwenden, so müssen Sie möglicherweise um es zu stoppen mehrmals, um es zu fangen in der Tat. Oft ist das problem ist irgendwo in der Mitte des call-stack. Alles, was erscheint auf mehr als ein stack-Beispiel wird, wenn Sie es ersetzen können, sparen Sie erhebliche Zeit.
Im Allgemeinen ist die Methode.
InformationsquelleAutor Mike Dunlavey
Es könnte etwas in der Erklärung Abschnitt, das wird lange dauern, bis auszuführen. Könnten Sie den code der gespeicherten Prozedur ?
InformationsquelleAutor dub
In Ihrem DBMS_OUTPUT Aussagen, die Sie teilen Ihr Ergebnis durch 1000. Nach all der Oracle-Dokumentation zusammen, die ich finden kann auf der dbms_utility.get_time Funktion Messen Sie die Zeit in 100ths von Sekunden, nicht 1000ths.
So, während Sie die Anzeige von 10 bis 40 Sekunden, es ist tatsächlich 100 (1 minute 40 Sekunden) , 400 (6 Minuten 40 Sekunden) Sekunden. Dies ist mehr inline mit 2 bis 8 Minuten sind Sie zu beobachten.
Check-out http://download-west.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_util.htm für weitere Informationen über die Funktion.
InformationsquelleAutor prof401
Ihre Zeit ist wahrscheinlich aufgrund einer großen Anzahl von Kontext-switches zwischen java und der Datenbank, wie SQL developer erfrischt auf Ihrem Bildschirm. um dies zu testen, führen Sie den test erneut in SQLPlus. Zu beheben, gehen Sie in Extras > Einstellungen - > Datenbank - > erweiterte Parameter an und bis Sie Ihre SQL Array-Fetch-Größe auf einen Wert irgendwo zwischen 150, - und 500, und (wenn Sie über die entsprechenden Treiber) überprüfen Sie die Verwendung von OCI - /Dicken-Fahrer im Feld.
InformationsquelleAutor Tom S
wenn Sie über die entsprechenden Berechtigungen (und wenn nicht, Fragen Sie Ihren Datenbankadministrator um Hilfe) vielleicht könnten Sie eine Abfrage der folgenden Ansichten:
können Sie dann überprüfen Sie die Ergebnisse
hier (http://www.remote-dba.net/oracle_10g_tuning/t_oracle_v$session_wait.htm)* ist eine Beschreibung, wie man die Ausgabe Lesen und hier ist noch mehr info auf die Ereignisse im inneren.
* Sie müssen kopieren Sie die url als $ vermasselt den link.
InformationsquelleAutor akf
So etwas, wie diese?
"Ich weiß nicht viel über die Oracle-Transaktions-Paradigma, aber ich Frage mich, wenn die commit innerhalb der Prozedur nicht wirklich einen Effekt haben, bis das Verfahren abgeschlossen ist, und das Verfahren ist nicht abgeschlossen, bis das ENDE erreicht ist. An dieser Stelle der eigentliche Prozess der Begehung der Transaktion beginnt, und dauert eine lange Zeit, wenn es Trigger und Einschränkungen der referenziellen Integrität beteiligt.
Diese Art von Verhalten wäre ähnlich wie DEFERRABLE INITIAL LATENTE Einschränkungen der referenziellen Integrität handeln.
Ich vermute, dass das vorgeschlagene system Tabelle Abfragen, würden Sie sagen, oder Sie könnten versuchen, ein Schritt durch das "Zeugs" Schritte in einer interaktiven Sitzung und sehen, was passiert.
Dies kann geschehen, in einigen Versionen von PL/SQL finden Sie unter oracledba.co.uk/tips/lgwr_dilemma.htm
Und, verpflichtet sind überraschenderweise ziemlich Billig.
InformationsquelleAutor
Was macht das Verfahren ?
Eine mögliche Erklärung könnte sein DBMS_OUTPUT.
Wenn SQL*Plus, Sie machen ein SET SERVEROUTPUT AUF, nachdem eine Anweisung ausgeführt wurde, hat der Kunde ein "hinter-den-Szenen" abrufen von Informationen, wurde gepuffert mit DBMS_OUTPUT.PUT_LINE. Ich denke, dass die SQL-Developer macht das gleiche.
So, wenn eine Menge Sachen, die geschoben wurde, DBMS_OUTPUT, dann die Ausführung der Prozedur schnell sein könnte, aber die hinter-den-Szenen-Sammlung, die sein könnte, wobei die Zeit (vor allem, wenn es ein langsames Netzwerk).
Anderen trick in SQL*Plus können Sie
SET TIMING ON (wird automatisch zeigen die verstrichene Zeit der Aussage)
und
ZEIT EINSTELLEN AUF (die zeigt die Zeit, in der SQL-Eingabeaufforderung).
So versuchen
Und die Ergebnisse sehen. Ich würde nicht erwarten, um zu sehen, jeder Zeit vermisst. Das heißt, die Kunden melden sollten, die vollen zwei Minuten.
Angenommen, es ist, ich würde mich mit der Spur (die DBMS_MONITOR-Befehl), und führen Sie einen tkprof auf das Ergebnis, um zu sehen, welche Konten für die 2 Minuten.
InformationsquelleAutor Gary Myers
Problem gelöst, aber ich verstehe immer noch nicht...
Sich das Leck, verursacht durch eine schlechte select-Anweisung begraben in einem anderen Verfahren, das heißt durch die anderen Verfahren. Optimiert habe ich es, jetzt läuft es wie Charme.
Fand ich die harte Weise, kommentieren Sie Zeile für Zeile... versucht und versucht.
Allerdings würd ich noch gerne wissen, warum die Zeiten waren absolut ungenau. Das war sehr irreführend, und kostete mich schon einige Zeit...
Also, gibt es etwas falsch mit der Art und Weise Schaffe ich mir die timestamps?
Wenn jemand Infos dazu, wäre ich froh, es zu hören.
Dank an Euch alle für Eure Hilfe mit diesem Problem.
Wie schon andere gesagt haben, Sie hatte Ihre Waage falsch. Dinge einfach zu halten, ich in der Regel nur Verwendung von Datums-Variablen und der DATEPART-bei der Messung der verstrichenen Zeit, wenn ich bin nicht besorgt über die sub-Sekunden-Genauigkeit. Ihr Datum arithmetische Ergebnis wird in einer Zahl ausgedrückt in Tagen, aber Sie können multiplizieren Sie ihn mit 24*60*60 zum konvertieren in Sekunden.
Argh... das ist peinlich... aber natürlich hast du Recht! vielen Dank an Euch beide...
InformationsquelleAutor PeterP
Oracle enthält einen profiler, der wird Ihnen sagen, die Höhe der aufgewendeten Zeit auf jede ausführbare Anweisung. dbms_profiler für 10g und früher, und es ist ein schicker version (die hierarchische profiler) in 11g.
Viel einfacher als mit Sätzen von dbms_utility und dbms_output-statements, und es gibt Ihnen viel mehr vollständige Informationen -- inklusive der Detailsuche in die aufgerufene Routine, wenn Sie die Rechte haben, um zu sehen, in den source code.
Ich bin froh, dass du dein problem gelöst. Das nächste mal, wenn, mit dem profiler wird es einfacher.
InformationsquelleAutor Jim Hudson