Oracle SQL-insert, große Datensätze effizient über die cursor verwenden und einzelne verpflichten
Den folgenden SQL-erstellt alle übereinstimmenden Datensätze aus zwei Tabellen, die identische schemas und geht dann Durchlaufen Sie den cursor, speichert dieses Ergebnis gesetzt. Ich mache eine Zeilen-insert mit einem commit am Ende dieser Funktion. Meine Frage ist, wie bekomme ich die maximale Leistung aus dieser Art der Abfrage? Code folgt:
BEGIN
DECLARE
CURSOR foo IS
SELECT * FROM tableOne to
WHERE EXISTS (SELECT * FROM tableTwo tt
WHERE TO.FOO = TT.FOO
AND TO.BAR = TT.BAR); --THIS TAKES 5 MINUTES (66 MILLION ROWS)
BEGIN
FOR nextFoo IN foo
LOOP
INSERT INTO tracker t
(id,foo,bar,baz)
VALUES(trackerSequence.nextval, nextFoo.foo,nextFoo.bar,nextFoo.baz);
END LOOP;
COMMIT;
END;
END;
Diese Abfrage kann nach oben von einer Stunde, und ich versuche, die Zeit verringern, die damit verbundenen Kosten. Ich werde die Verarbeitung mit 140 Millionen Datensätze im Allgemeinen, so erwarte ich die doppelte Menge, wie lange dieser Prozess dauert. Alle Spalten indiziert sind.
Version Informationen:
10g 10.2
- :Warum haben Sie nicht versucht, bulk insert?
- die ersten test-Fälle, die ich geliefert wurde, waren für 10k Datensätze. Ich habe laufen in eine Skala problem Recht deutlich. Bitte postet eine Antwort, die verwendet bulk insert, als wäre das von Vorteil.
- :Was ist Ihre version von Oracle, die Sie verwenden?
- Oracle 10g 10.2
Du musst angemeldet sein, um einen Kommentar abzugeben.
wie etwa
Frage ich mich, ob das wäre besser optimiert.
Außerdem sicher, dass die tracker -Tabelle Indizes deaktiviert sind, während einfügen..
ROLLBACK
Segmenten und kann zu schweren archive log verstopfen. Vor allem, wenn die Verarbeitung 140 mn Zeilen.OK, ich weiß, Sie wollte den cursor...
Der einzige wirkliche Vorteil der Verwendung der cursor ist zu verpflichten, alle 10k? Zeilen bei der Verarbeitung, viele Daten zu vermeiden, füllen die Protokolle bis.
Es sei denn, Sie wirklich brauchen, der cursor ist, Beseitigen Sie die Zeile der Verarbeitung.
Der direkte Pfad Einfügen Hinweis, wie vorgeschlagen
insert/*+append*/ into tracker....
BULK COLLECT
Sie sollte sich wirklichLIMIT
. Abrufen von 66 Millionen Zeilen von Daten in die Datenbank der PGA wird die performance-Probleme. Wenn jede Zeile nur 100 bytes, zum Beispiel, dass erfordern würde, ~6 GB PGA Platz. Die meisten Datenbank-Server sind nicht konfiguriert, um zu ermöglichen, dass viel auf der PGA-Platz konsumiert werden. Wenn Sie zufällig auf einer Maschine, die Tonnen von RAM zugewiesen Oracle, ein Prozess, kauen bis 6 GB PGA geht, um einige ernsthafte negative Auswirkungen auf die Leistung auf andere Prozesse in der Datenbank.LIMIT
nicht wirklich abhängen auf dem server. Die effizientesteLIMIT
ist in der Regel irgendwo zwischen 100 und 1000. Sie können versuchen, verschiedene Möglichkeiten für Ihre bestimmten Prozess, obwohl es unwahrscheinlich ist, dass der Unterschied riesig sein. Ein "LIMIT" von 100 eliminiert 99% der Rahmen verschiebt sich, eineLIMIT
1000 beseitigt 99,9% der Kontext verschiebt. Es ist unwahrscheinlich, dass Sie gehen, um viel mehr Leistung zu gewinnen von der Beseitigung, die letzten 0,1% des Kontext-Verschiebungen und die Erhöhung der Menge von RAM Sie verwenden wahrscheinlich mehr hinzufügen zu Ihrem Kopf, als Sie gewinnen.Ersten - wie können Sie optimieren Sie Ihre PL/SQL-Leistung:
Zweiten - nicht den Einsatz mit PL/SQL. Verwenden BulkLoading (wie schon von einigen Kommentaren). Sie können leicht finden viele Infos auf BulkLoading wenn Sie bei Google nach "oracle sql-loader"
Habe ich fast immer erhalten bessere performance mit solcher bulk-Daten einfügt, indem eine Kombination von
BITMAP INDEXES
und mithilfe eines DPL (Direct Path Load), d.h. mit der Verwendung von Tipp/*+ APPEND+/
.Ich würde auch davon ausgehen, dass mit diesem hätten Sie die korrekten Indizes auf beiden
TT.FOO, TT.BAR
undTO.FOO, TO.BAR
.So somethink wie
Auch - im Hinterkopf Behalten, dass die
EXIST
Klausel könnte beißen Sie wieder unter bestimmten Situationen. Also, möchten Sie vielleicht verwenden Sie einfache outer-joins.Erinnern - DPL (Direct path load) wird nicht immer zu einer Verbesserung der Leistung Ihrer Abfrage, kann es verbessern (oder Hilfe), wenn Sie Ihre Tabelle richtig partitioniert.
Erklären Sie planen, auf diese Abfragen, um herauszufinden, die besten.
Auch, (wie man der Antwort schon erwähnt) nicht Begehen am Ende, aber nicht verpflichten, die auf jeden Datensatz entweder. Es würde vorgeschlagen werden, um eine benutzerdefinierte commit-Punkt etwas ähnliches wie während der Verwendung
LIMIT XXXX
währendBULK COLLECT
ing. Die übergabe Punkte geregelt, wie groß IhreROLLBAK
Segmente sind. Sie können auch Ihre benutzerdefinierten Commit-Punkte (so einfach wie als Zähler) prozedural (z.B. in PLSQL-BLOCK).Abfrage-performance hängt auch von der
HWM
Ihrer Tabelle (um genau zu sein), würden Sie fast immer wollen, um unter derHWM
der Tabelle. WährendTRUNCATE
auf dieTRACKER
Tabelle wird dazu beitragen, diese, die vorherigen Daten darauf verloren, so könnte dies kaum sein, hier eine Lösung. Folgen Sie dieser AskTom link zu erfahren, wie manHWM
.INSERT
Verfahren gelegt werden, die auf eine Echtzeit-Anwendung, seinen besten geeignet, da eine 'nightly' batch-job.Habe ich Folgendes gefunden wird tun 130 Millionen Einsätzen in etwa 49 Minuten.