2016-03-21 2 views
0

Ich versuche, Daten aus der Tabelle zu löschen, deren Primärschlüssel von mehreren Tabellen mit großen Daten verwiesen wird. Ich habe eine Abfrage versucht, die viel Zeit in Anspruch nimmt, dann dachte ich daran, die Einschränkungen fallen zu lassen und sie neu aufzubauen, aber gibt es eine Alternative dafür, wie Code in einem anonymen Block zu schreiben, um besser zu funktionieren !! Bitte lassen Sie mich Ihre Vorschläge wissen.Wie kann ich eine Abfrage löschen?

DELETE FROM <table_name1> a 
    WHERE 
    a.status='I' 
    AND NOT EXISTS 
      (SELECT b.id 
      FROM <table_name2> b 
      WHERE a.id=b.id) 
    AND NOT EXISTS 
      (SELECT c.id 
      FROM <table_name3> c 
      WHERE a.id=c.id);  
    COMMIT; 

Danke,

Pradeep

+0

Überprüfen Sie den Ausführungsplan –

Antwort

0

denke ich CBO Hashverknüpfung mit TABLE ACCESS FULL table_name1 und INDEX Tabellenname2 und table_name3 FAST FULL SCAN tun wird. Vielleicht wird besser sein, alle IDs nur INDEX FAST FULL SCAN Precalc und nach als ausgewählten Zeilen löschen INDEX ACCESS:

declare 
    v_list is table of number; 
begin 
    select t1.id 
    bulk collect into v_list 
    from <<table_name1>> t1 
    left join <<table_name2>> t2 on (t1.id = t2.id) 
    left join <<table_name3>> t3 on (t1.id = t3.id) 
    where nvl(t2.id,t3.id) is null; 

    forall i in v_list.first..v_list.last 
    delete from <<table_name1>> t 
    where t.id = v_list(i) 
    and t.status = 'I'; 

    commit; 
end; 

Bitte versuchen Sie diese/Aber ich bin nicht sicher, dass es Ihnen hilft. Vielen Dank.

0

Ich würde versuchen, die Unterabfragen unabhängig von der umgebenden Aussage zu machen. Daher sind die Unterabfragen immer gleich, müssen nur einmal berechnet werden und die Aussage könnte besser optimiert werden.

DELETE FROM <table_name1> a 
    WHERE 
    a.status='I' 
    AND a.id NOT IN 
      (SELECT b.id 
      FROM <table_name2> b) 
    AND a.id NOT IN 
      (SELECT c.id 
      FROM <table_name3> c);