2016-04-25 6 views
1

Ich habe eine Tabelle mit 17 Milliarden Zeilen. Ich möchte einige von denen löschen, die in einer anderen Tabelle vorhanden sind.Oracle DELETE Zerschlagung TEMP Raum

Ich habe versucht, eine Löschanweisung, parallelisiert, die nicht abgeschlossen, weil der temporäre Speicherplatz nicht genug war.

delete /* + PARALLEL(a, 32) */ 
    from a 
where (a.key1, a.key2) in 
     (select /*+ PARALLEL(b, 16) */ 
       key1, 
       key2 
      from b); 

Dann habe ich versucht, create table as select, die aus dem gleichen Grund auch fehlgeschlagen.

create table a_temp parallel 32 nologging as 
     select /* + PARALLEL (a, 32) */ 
       key1, 
       key2, 
       rest_of_data 
     from a 
     where (a.key1, a.key2) not in 
       (select key1, key2 from b); 

Eine reguläre (ohne PARALLEL) Löschung dauerte mehr als einen Tag, also musste ich es beenden.

Gibt es eine Möglichkeit, temporären Speicherplatz freizugeben, da er nicht mehr benötigt wird, während der Ausführung des Löschvorgangs?

Gibt es eine andere Möglichkeit, dies zu tun?

EDIT: B hat 173 Millionen Datensätze, und fast 16 Milliarden Datensätze müssen gelöscht werden (fast die gesamte Tabelle). Es gibt keine Indizes für die Tabelle.

EDIT2: Das erklären Plan für die Tabelle erstellen, ist wie folgt:

CREATE TABLE STATEMENT, GOAL = ALL_ROWS   6749420 177523935 10828960035 
PX COORDINATOR     
    PX SEND QC (RANDOM) SYS :TQ10001 6740915 177523935 10828960035 
    LOAD AS SELECT (HYBRID TSM/HWMB) USER A_TEMP   
    OPTIMIZER STATISTICS GATHERING   6740915 177523935 10828960035 
    MERGE JOIN ANTI NA   6740915 177523935 10828960035 
     SORT JOIN   6700114 17752393472 745600525824 
     PX BLOCK ITERATOR   45592 17752393472 745600525824 
     TABLE ACCESS FULL USER A 45592 17752393472 745600525824 
     SORT UNIQUE   40802 173584361 3298102859 
     PX RECEIVE   5365 173584361 3298102859 
     PX SEND BROADCAST SYS :TQ10000 5365 173584361 3298102859 
     PX BLOCK ITERATOR   5365 173584361 3298102859 
      TABLE ACCESS FULL USER B 5365 173584361 3298102859 

Vielen Dank im Voraus

+0

Wie viele Zeilen planen Sie beim Löschen? Wie viele Zeilen sind in b? Gibt es einen Index für 'key1, key2'? Was ist der Abfrageplan? Ich würde erwarten, dass der Optimierer diese Abfrage als "Existieren" umschreiben würde, aber Sie könnten es möglicherweise selbst versuchen. –

+0

Können Sie den EXPLAIN-Plan für die 'CREATE TABLE' veröffentlichen? Führen Sie 'explave plan for create table ...' aus und führen Sie 'select * from table (dbms_xplan.display);' aus und geben Sie die gesamten Ergebnisse hier ein. –

Antwort

0

Ich habe es geschafft, mit einer anderen Lösung.

Ich erstellte manuell die a_temp Tabelle und tat eine insert mit einem APPEND PARALLEL Hinweis. Der Temp-Raum wurde nicht überschritten und die Einsätze funktionierten perfekt. Hier

ist der Code:

create table a_temp(..); 

insert /* + APPEND PARALLEL(a_temp, 32) */ 
    into a_temp(...) 
select /* + PARALLEL(a, 32) */ 
     (...) 
    from a 
where not exists 
     (select /* + PARALLEL(b, 16) */ 
       '1' 
      from b 
     where a.key1 = b.key1 
      and a.key2 = b.key2) 
0

, um dieses Problem in der Vergangenheit zu lösen, habe ich an einem in Chargen von ~ 1 M gelöscht Zeit. Nach langem Suchen nach einer saubereren Lösung bestand ein DBA darauf, diesen Ansatz zu verfolgen.

Das war mein Workflow:

ich Python verwendet und das cx_Oracle Modul in den PK-Werte für die zu-gelöschten Datensätze zu lesen, eingesteckt sie iterativ in einen executemany Aufruf als Bindevariablen und engagierte nach jeder Iteration.

Wenn Sie mit einem Parallel Execution Ansatz haften möchten: Denken Sie daran, ALTER SESSION ENABLE PARALLEL DML zu verwenden, so dass Ihre merge oder löschen zu parallel ausgeführt wird. Schauen Sie sich diesen tollen Blog-Eintrag an, der Sie durch folgendes führt: https://dioncho.wordpress.com/2010/12/10/interpreting-parallel-merge-statement/

+0

Hallo Deano, ich dachte Batch-Löschungen in PL/SQL, aber in der Regel SQL ist schneller dank PL/SQL, und die Update-Anweisung ohne Parallel dauerte mehr als einen Tag. Würde Python die Dinge beschleunigen?Ich denke, die Datenbankarbeit ist immer noch da, nur mit mehr Aufwand, oder? Vielen Dank! – jcd

+0

Python beschleunigt die Dinge nicht automatisch. Der Vorteil hierbei ist, dass Sie SQL direkt auf der Datenbank in bestimmten Batchgrößen ausführen können. Python übergibt nur die Parameter und sendet Ihr SQL an Oracle. Ich kann mir vorstellen, dass Sie diese Art von Strategie mit einer Vielzahl von Tools verwenden können. – Deano

+0

Bearbeitet, um Tipps zur parallelen Ausführung hinzuzufügen – Deano