2016-11-29 2 views
0

Ich versuche, eine hierarchische Struktur auf Orakel gehen und ich habe ernsthafte Probleme mit der Leistung. Dies ist mein Code:Die Verwendung eines Feldes in Update drastisch verlangsamt die Abfrage

UPDATE {table} t1 
SET (t1.{column2}) = (
    SELECT max(t2.{date}) FROM {table2} t2 
    WHERE t2.{column} in(
     SELECT t3.{column} 
     FROM {table3} t3 
     START WITH t3.{columnt3} = 'blablabla' 
     CONNECT BY t3.{columnt3} = PRIOR t3.{column} 
     )) 
WHERE t1.{column1} = 'blablabla' 

Dieser Code funktioniert und läuft unter einer Sekunde. Ersetzen Sie jetzt die erste 'blablabla' mit t1. {Spalte1} (diese beiden sind äquivalent) ergibt mehr als eine Minute Ausführungszeit. Der Code sieht dann wie folgt aus:

UPDATE {table} t1 
SET (t1.{column2}) = (
    SELECT max(t2.{date}) FROM {table2} t2 
    WHERE t2.{column} in(
     SELECT t3.{column} 
     FROM {table3} t3 
     START WITH t3.{columnt3} = t1.{column1} 
     CONNECT BY t3.{columnt3} = PRIOR t3.{column} 
     )) 
WHERE t1.{column1} = 'blablabla' 

Weiß jemand, den Grund für dieses seltsame Problem?

Edit: Hier ist der Plan für die obere (die Arbeits) Abfrage erklären: first explain plan

Und hier die man für die zweite (die gebrochen) Abfrage: second explain plan

Wie Sie kann sehen, die Laufzeit explodiert gerade durch das Durchsuchen von t2, einem sehr großen Tisch. Aber warum passiert das? Und gibt es einen Grund, warum das passiert?

Edit 2:

Vielleicht der ursprünglichen Code hilft ein bisschen mehr:

UPDATE tmp_obsolete t1 
SET (liefertermin) = (
    SELECT max(versand_termin) FROM ropd7.pkvp 
    WHERE artikel_nr in(
     SELECT pstp.artikel_nr 
     FROM ropd7.pstp 
     START WITH pstp.komponenten_art_nr = 'XX.XX.XX.XX.XX' 
     CONNECT BY pstp.komponenten_art_nr = PRIOR pstp.artikel_nr 
     )) 
WHERE t1.artikel_nr = 'XX.XX.XX.XX.XX'; 


UPDATE tmp_obsolete t1 
SET (liefertermin) = (
    SELECT max(versand_termin) FROM ropd7.pkvp 
    WHERE artikel_nr in(
     SELECT pstp.artikel_nr 
     FROM ropd7.pstp 
     START WITH pstp.komponenten_art_nr = t1.artikel_nr 
     CONNECT BY pstp.komponenten_art_nr = PRIOR pstp.artikel_nr 
     )) 
WHERE t1.artikel_nr = 'XX.XX.XX.XX.XX'; 
+1

Haben Sie die Ausführungspläne verglichen? –

+2

'CONNECT BY t3. {Columnt3} = t3. {Spalte}' ist diese Zeile korrekt? Normalerweise erwarten Sie, dass das PRIOR-Schlüsselwort irgendwo drin steht. I.e. 'CONNECT BY PRIOR t3. {Columnt3} = t3. {Spalte}' oder 'CONNECT BY t3. {Columnt3} = PRIOR t3. {Spalte}', je nachdem, wie Ihre Hierarchie definiert ist – Boneist

+0

@WernfriedDomscheit: ja, ich habe sie verglichen und der spätere explodierte gerade. Aber das hilft nicht sehr, denn ich kann immer noch nicht erklären, warum das passiert. –

Antwort

0

ich keine gute Lösung gefunden, dies zu machen Abfrage läuft effizient, so versuchte ich mit einer einfachen PL/SQL-Funktion, die das Maximum (Datum) zurückgibt, wenn Sie den Parameter angeben. Und das funktioniert ziemlich gut. Gehen ~ 1000 Einträge in weniger als 400ms.

Vielen Dank für Ihre Hilfe.

0

die Abfrage Hilfe Wird Umschreiben:

UPDATE {table} t1 
SET (t1.{column2}) = (
    SELECT max(t2.{date}) 
     FROM {table2} t2 
     JOIN {table3} t3 
     ON t2.{column} = t3.{column} 
    START WITH t3.{columnt3} = t1.{column1} 
    CONNECT BY t3.{columnt3} = PRIOR t3.{column}) 
WHERE t1.{column1} = 'blablabl'; 
+0

Vielen Dank für die Antwort, aber ich habe immer noch einen vollen Tabellenzugriff auf t2, also dauert es immer noch ewig zu laufen. –

Verwandte Themen