2017-05-27 1 views
2

Wollte eine wichtige Aussage optimieren, die länger dauert, um zu beenden.optimieren Abfrage einfügen mit minus oracle

Grundsätzlich wird der Prozess:

1) Einfügen von Daten auf NG_ORGANIZATION_CATEGORY_GTMP von 5-Einsätzen, eine nach der anderen. Diese DML benötigt 10 Sekunden pro Abfrage. Aus der letzten Spur eingefügt dies DML die unten Anzahl der Zeilen:

Insert 1 - 292770 
Insert 2 - 106648 
Insert 3 - 67358 
Insert 4 - 47775 
Insert 5 - 6147 

2) Problematische Abfrage ausführen, Einfügen um 6 Zeilen nur auf dem Tisch NG_ORGANIZATION_CATEGORY (diese Tabelle hat rund 414K Zeilen).

INSERT INTO NG_ORGANIZATION_CATEGORY(ORGANIZATION_ID,CATEGORY_CODE,ADDED_DATE) 
    SELECT ORGANIZATION_ID,CATEGORY_CODE,:B1 AS ADDED_DATE 
    FROM NG_ORGANIZATION_CATEGORY_GTMP 
    WHERE (ORGANIZATION_ID,CATEGORY_CODE) IN (
      SELECT ORGANIZATION_ID,CATEGORY_CODE 
      FROM NG_ORGANIZATION_CATEGORY_GTMP 
      MINUS 
      SELECT ORGANIZATION_ID,CATEGORY_CODE 
      FROM NG_ORGANIZATION_CATEGORY); 

3) Löschen Sie die Daten aus der Tabelle NG_ORGANIZATION_CATEGORY. Es ist auch gut.

DELETE FROM NG_ORGANIZATION_CATEGORY 
WHERE 
(ORGANIZATION_ID,CATEGORY_CODE) IN (SELECT ORGANIZATION_ID,CATEGORY_CODE 
    FROM NG_ORGANIZATION_CATEGORY MINUS SELECT ORGANIZATION_ID,CATEGORY_CODE 
    FROM NG_ORGANIZATION_CATEGORY_GTMP); 

Unten ist die Spur für den problematischen Einsatz:

SQL ID: gwxs083gcfdd2 Plan Hash: 2436575860 

INSERT INTO NG_ORGANIZATION_CATEGORY(ORGANIZATION_ID,CATEGORY_CODE,ADDED_DATE) 
    SELECT ORGANIZATION_ID,CATEGORY_CODE,:B1 AS ADDED_DATE FROM 
    NG_ORGANIZATION_CATEGORY_GTMP WHERE (ORGANIZATION_ID,CATEGORY_CODE) IN (
    SELECT ORGANIZATION_ID,CATEGORY_CODE FROM NG_ORGANIZATION_CATEGORY_GTMP 
    MINUS SELECT ORGANIZATION_ID,CATEGORY_CODE FROM NG_ORGANIZATION_CATEGORY) 



call  count  cpu elapsed  disk  query current  rows 
------- ------ -------- ---------- ---------- ---------- ---------- ---------- 
Parse  1  0.00  0.00   0   0   0   0 
Execute  1 6704.07 6705.98   2 424814954   25   6 
Fetch  0  0.00  0.00   0   0   0   0 
------- ------ -------- ---------- ---------- ---------- ---------- ---------- 
total  2 6704.07 6705.98   2 424814954   25   6 

Misses in library cache during parse: 1 
Misses in library cache during execute: 1 
Optimizer mode: ALL_ROWS 
Parsing user id: 146  (recursive depth: 1) 
Number of plan statistics captured: 1 

Rows (1st) Rows (avg) Rows (max) Row Source Operation 
---------- ---------- ---------- --------------------------------------------------- 
     0   0   0 LOAD TABLE CONVENTIONAL (cr=424814954 pr=2 pw=0 time=923492126 us) 
     6   6   6 FILTER (cr=424814953 pr=0 pw=0 time=1667461141 us) 
    414050  414050  414050 TABLE ACCESS FULL NG_ORGANIZATION_CATEGORY_GTMP (cr=1023 pr=0 pw=0 time=121231 us cost=2 size=35 card=1) 
     6   6   6 MINUS (cr=424813930 pr=0 pw=0 time=2409881660 us) 
    414050  414050  414050  SORT UNIQUE NOSORT (cr=423573150 pr=0 pw=0 time=2406932080 us cost=3 size=35 card=1) 
    414050  414050  414050  TABLE ACCESS FULL NG_ORGANIZATION_CATEGORY_GTMP (cr=423573150 pr=0 pw=0 time=2406112290 us cost=2 size=35 card=1) 
    414044  414044  414044  INDEX UNIQUE SCAN NG_ORG_CATEGORY_PK (cr=1240780 pr=0 pw=0 time=2134347 us cost=2 size=11 card=1)(object id 108100) 


Elapsed times include waiting on following events: 
    Event waited on        Times Max. Wait Total Waited 
    ---------------------------------------- Waited ---------- ------------ 
    gc cr grant 2-way        1  0.00   0.00 
    db file sequential read       2  0.13   0.13 
    gc current grant 2-way       6  0.00   0.00 
******************************************************************************** 

Könnten Sie mir bitte helfen und lassen Sie mich wissen, wie ich diese Abfrage Tuning kann? Ich habe mir einen Parallelhinweis ausgedacht, der aber wegen der MINUS in der Abfrage ignoriert wird.

Bitte lassen Sie mich wissen, wenn Sie eine Idee haben und wenn Sie weitere Informationen benötigen.

Schätzen Sie Ihre Aufmerksamkeit darauf.

Vielen Dank im Voraus,

Will

Antwort

0

Sie eine innere Verknüpfung statt einer where() IN

wählen verwenden könnte
INSERT INTO NG_ORGANIZATION_CATEGORY(ORGANIZATION_ID,CATEGORY_CODE,ADDED_DATE) 
SELECT ORGANIZATION_ID,CATEGORY_CODE,:B1 
FROM NG_ORGANIZATION_CATEGORY_GTMP 
INNER JOIN (
    SELECT ORGANIZATION_ID,CATEGORY_CODE 
    FROM NG_ORGANIZATION_CATEGORY_GTMP 
    MINUS 
    SELECT ORGANIZATION_ID,CATEGORY_CODE 
    FROM NG_ORGANIZATION_CATEGORY 
) T1 on NG_ORGANIZATION_CATEGORY_GTMP.ORGANIZATION_ID = T1.ORGANIZATION_ID 
      and NG_ORGANIZATION_CATEGORY_GTMP.CATEGORY_CODE = T1.CATEGORY_CODE 

und eine einfache Tipps, entfernen Sie die Alias-Form (nicht sinnvoll)

+0

Vielen Dank .. Ich werde es versuchen! – Will

+0

Hallo @scaisEdge ... Ich arbeitete und lief in weniger als 1 Sekunde! Ich muss nur die Daten bestätigen, aber ich habe vor dem Einfügen eine Zählung MINUS ausgeführt und es hat die gleiche Anzahl von Daten eingefügt. Ich werde am Montag mit den Entwicklern sprechen und auf diesen Beitrag zurückkommen! Für jetzt, DANKE, du bist der MANN! – Will

+0

gut, wenn meine Antwort richtig ist, bitte markieren Sie es als akzeptiert ... siehe hier http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – scaisEdge

0

Gemäß Ihrer Abfrage möchten Sie Daten nur dann in die gtmp-Tabelle einfügen, wenn sie nicht in der Kategorietabelle vorhanden sind. können Sie die folgende Abfrage versuchen:

INSERT INTO NG_ORGANIZATION_CATEGORY(ORGANIZATION_ID,CATEGORY_CODE,ADDED_DATE) 
    SELECT ORGANIZATION_ID,CATEGORY_CODE,:B1 AS ADDED_DATE FROM 
    NG_ORGANIZATION_CATEGORY_GTMP T1 WHERE NOT EXISTS (
SELECT 1 FROM NG_ORGANIZATION_CATEGORY T2 WHERE T1.ORGANIZATION_ID=T2.ORGANIZATION_ID AND T1.CATEGORY_CODE=T2.CATEGORY_CODE); 
0

können Sie eine MERGE-Anweisung nur mit den Zeilen aus der Quelltabelle die Zieltabelle zu füllen, die nicht existieren:

merge into ng_organization_category noc 
using (select distinct organization_id, 
       category_code 
     from ng_organization_category_gtmp) gtmp 
    on (gtmp.organization_id = noc.organization_id 
     and gtmp.category_code = noc.category_code) 
when not matched then 
    insert (organization_id, category_code, added_date) 
    values (gtmp.organization_id, gtmp.category_code, :B1) 
/

Die DISTINCT in Die USING-Unterabfrage ist möglicherweise nicht erforderlich, sie hängt von Ihren Quelldaten ab. (Ihre vorhandene INSERT-Anweisung würde mehrere Instanzen von einfügen, wenn die GTMP-Tabelle diese enthält, also spielt es keine Rolle.)

+0

Hallo @ APC .. danke für Ihre Hilfe! Ich werde warten, bis der DEV den Vorschlag von ScaisEdge validiert, wenn es nicht nützlich ist .. Ich werde Ihre Indikation versuchen! Schätze wirklich deine Hilfe. – Will