Ich habe ein PL/SQL-Skript, das Datensätze von Personen (~ 4 Millionen) wiederholt und führt mehrere Updates (~ 100) und eine einzige Löschanweisung (alle diese Updates und löschen sind in verschiedenen Tabellen). Das Problem, mit dem ich konfrontiert bin, ist, dass die eine delete-Anweisung etwa die Hälfte der Laufzeit benötigt. Ich verstehe, dass wenn Sie eine Löschanweisung ausführen, muss es den Index aktualisieren, aber ich finde es ziemlich lächerlich. Ich teste gerade dieses Skript mit einem Thread unter Verwendung dbms_parallel_execute
, aber ich plane, dieses Skript Multithread.Mehrere kleine löscht
Ich Ausführung eine Abfrage ähnlich der folgenden:
DELETE FROM table1 t1
WHERE (t1.key1, t1.key2) IN (SELECT t2.key1, t2.key2
FROM table2 t2
WHERE t2.parm1 = 1234
AND t2.parm2 = 5678).
folgende Fakten:
- Table2 (~ 30 Millionen Datensätze) ist ~ 10-mal größer als table1 (~ 3 Millionen Datensätze) .
- gibt einen Primärschlüssel für Tabelle 1 ist (Key1, Key2)
- gibt ein Primärschlüssel auf table2 ist (Key1, Key2)
- Es ist ein Index für Tabelle2 (parm1, parm2)
- I haben behinderte Die Fremdschlüsseleinschränkung für Tabelle1 (Schlüssel1, Schlüssel2), die Tabelle2 referenziert (Schlüssel1, Schlüssel2)
Es gibt keine weiteren Einschränkungen für Tabelle1, aber viele Einschränkungen für Tabelle2.
Alle Auslöser für Tabelle1 haben für diese Abfrage mit geringeren Kosten aufkommt
- Der erklären Plan deaktiviert worden als die von vielen meiner Update-Anweisungen (aber ich weiß, dass dies nicht für viel kostet Konto).
Erklären Plan Ausgabe:
OPERATION OPTIONS OBJECT_INSTANCE OBJECT_TYPE OPTIMIZER SEARCH_COLUMNS ID PARENT_ID DEPTH POSITION COST CARDINALITY BYTES CPU_COST IO_COST TIME
------------------------------------ ---------------------------------------------------------------------------------------------------- -------------------------------------------- ------------------------------------ ---------------------------------------------------------------------------------------------------- -------------------------------------------- -------------------------------------------- -------------------------------------------- -------------------------------------------- -------------------------------------------- -------------------------------------------- -------------------------------------------- -------------------------------------------- -------------------------------------------- -------------------------------------------- --------------------------------------------
DELETE STATEMENT ALL_ROWS 0 0 5 5 1 36 38043 5 1
DELETE 1 0 1 1
NESTED LOOPS 2 1 2 1 5 1 36 38043 5 1
TABLE ACCESS BY INDEX ROWID 2 TABLE ANALYZED 3 2 3 1 4 1 25 29022 4 1
INDEX RANGE SCAN INDEX ANALYZED 1 4 3 4 1 3 1 21564 3 1
INDEX UNIQUE SCAN INDEX (UNIQUE) ANALYZED 2 5 2 3 2 1 1 11 9021 1 1
ich mich gefragt, ob es eine Möglichkeit gab, um diese schneller gehen zu machen löschen. Ich habe versucht, eine bulk delete
zu tun, aber es schien nicht die Laufzeit zu verbessern. Wenn es irgendeine Möglichkeit gäbe, alle Löschungen auszuführen und den Index danach zu aktualisieren, vermute ich, dass es schneller laufen würde. Offensichtlich ist es nicht möglich, eine create-Tabelle aus einer Auswahl zu erstellen, da ich Datensätze (und mehrere Bedingungen durchlaufend) von einer anderen Tabelle durchlaufen lasse, um das Löschen durchzuführen.
Ist Ihr Tisch zufällig index-organisiert? Versuchen Sie 'SELECT IOT_TYPE VON ALL_TABLES WHERE TABLE_NAME = 'MYTABLENAME''. Wenn das Ergebnis nicht NULL ist, ist es index-organisiert. –
Das Ergebnis ist NULL für beide Tabellen. – Mocking
Bitte bewahren Sie die Formatierung von der EXPLAIN-Ausgabe auf. Der Einzug ist wichtig, um ihn zu analysieren. –