2015-06-30 8 views
6

ich die unten Abfrage haben. was die Leistung aufgrund der Unterabfrage verlangsamt. Ich habe viel versucht, Join statt Subquery hinzuzufügen. aber vergeblich. Kann mir jemand sagen, wie ich diese Abfrage mit JOIN umschreiben kann?Notwendigkeit dieser SQL-Abfrage zu optimieren die Leistung zu verbessern

update Table_1 
set status = 'Status_2' 
where status ='status_1' and (col_1, col_2, col_3, nvl(col_4,0), col_5) in ( 
       select col_1, col_2, col_3, nvl(col_4,0), col_5 from Table_2 where status ='Status_0'); 

Bitte beachten Sie die SELECT * FROM table(DBMS_XPLAN.Display); unter

Plan hash value: 1290346170 
------------------------------------------------------------------------------------------------------ 
| Id | Operation      | Name     | Rows | Bytes | Cost (%CPU)| Time  | 
------------------------------------------------------------------------------------------------------ 
| 0 | UPDATE STATEMENT    |      |  1 | 376 | 456 (3)| 00:00:06 | 
| 1 | UPDATE      | Table_1    |  |  |   |   | 
| 2 | NESTED LOOPS    |      |  |  |   |   | 
| 3 | NESTED LOOPS    |      |  1 | 376 | 456 (3)| 00:00:06 | 
| 4 |  SORT UNIQUE    |      |  1 | 316 | 454 (3)| 00:00:06 | 
|* 5 |  TABLE ACCESS FULL  | Table_2    |  1 | 316 | 454 (3)| 00:00:06 | 
|* 6 |  INDEX RANGE SCAN   | Table1_INDEX   |  1 |  |  1 (0)| 00:00:01 | 
|* 7 | TABLE ACCESS BY INDEX ROWID| Table_1    |  1 | 60 |  1 (0)| 00:00:01 | 
------------------------------------------------------------------------------------------------------`enter code here` 
+2

Bitte führen Sie 'EXPLAIN PLAN FÜR your_query'' dann SELECT * FROM Tabelle (DBMS_XPLAN.Display) ', dann kopieren Sie es ausgegeben ist und es um die Frage einfügen. – krokodilko

+0

@kordirko, bitte sehen Sie sich das Ergebnis an. – Msn

+0

@Msn Die geschätzte Zeit beträgt nur 6 Sekunden, was ziemlich schnell ist. Wie lange dauert die Abfrage? –

Antwort

2

es besser Funktioniert, wenn Sie es so machen?

update 
    (select Table_1.status 
    from Table_1 
     join Table_2 on 
      Table_1.col_1 = Table_2.col_1 
     and Table_1.col_2 = Table_2.col_2 
     and Table_1.col_3 = Table_2.col_3 
     and nvl(Table_1.col_4, 0) = nvl(Table_2.col_4, 0) 
     and Table_1.col_5 = Table_2.col_5 
    where Table_1.status = 'status_1' 
     and Table_2.status = 'Status_0') 
set status = 'Status_2' ; 
+1

Dies ist die richtige Antwort, aber @Msn muss Folgendes beachten: Wenn (col_1, col_2, col_3, col_5) nicht den Primärschlüssel von Table_1 und Table_2 enthält, wirft Oracle einen ORA-01779-Fehler (schlüsselerhaltene Tabellen). – acesargl

+0

@Wernfried, erhalten den Fehler "QL-Fehler: ORA-01779: kann eine Spalte nicht ändern, die auf eine nicht Schlüssel-beibehaltene Tabelle". sollte ich zusammengesetzte Schlüssel all diese coumns machen? – Msn

0

Mit einer with Aussage und die Materialized Hinweis Sie die Daten von table_2 in einer globalen temporären Tabelle vorspannen kann. Dies könnte die Leistung Ihrer Abfrage verbessern.

+0

kann man einen Code-Ausschnitt hinzufügen, wie kann ich das tun? – Msn

+0

Ich kann es versuchen. Ich bin am Handy. Mit ASD als (select/* + * materialisiert/col_1, col_2, col_3, nvl (col_4,0), col_5 von table_2 wo status = 'Status_0') aktualisieren Table_1 gesetzt status = 'status_2' where status = 'Status_1' und (col_1, col_2, col_3, nvl (col_4,0), col_5) in (select * from ASD) – hsstan

+0

mit dem undokumentierten materialisiert Hinweis macht keinen Sinn, es sei denn der gemeinsame Tabellenausdruck mehr als einmal verwendet wird. –