2014-02-05 115 views
0

我有一個查詢,如下優化甲骨文更新選擇

UPDATE CONVERTED T1 
    SET PARENTID = (SELECT MAX(ID) FROM 
        CONVERTED T2 WHERE T2.ID < T1.ID 
        AND T1.PREVOBJNUM = T2.OBID) 

它需要幾個小時來運行他們的是100萬條記錄,它是不必爲每一行執行子查詢。有沒有一種方法來優化查詢運行速度更快?

編輯:這裏是xplan

Plan hash value: 3177327108 

---------------------------------------------------------------------------------------------- 
| Id | Operation      | Name   | Rows | Bytes | Cost (%CPU)| Time  | 
---------------------------------------------------------------------------------------------- 
| 0 | UPDATE STATEMENT    |    | 1053K| 31M| 576M (1)|802:56:03 | 
| 1 | UPDATE      | CONVERTED |  |  |   |   | 
| 2 | TABLE ACCESS FULL   | CONVERTED | 1053K| 31M| 84276 (1)| 00:07:03 | 
| 3 | SORT AGGREGATE    |    |  1 | 17 |   |   | 
|* 4 | TABLE ACCESS BY INDEX ROWID| CONVERTED |  1 | 17 | 547 (1)| 00:00:03 | 
|* 5 |  INDEX RANGE SCAN   | CONVERTED_PK | 9478 |  | 22 (0)| 00:00:01 | 
---------------------------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

    4 - filter("T2"."OBID"=:B1) 
    5 - access("T2"."ID"<:B1) 

,這裏是表DLL

-------------------------------------------------------- 
-- DDL for Table CONVERTED 
-------------------------------------------------------- 

    CREATE TABLE "AMS"."CONVERTED" 
    ( "ID" NUMBER(10,0), 
    "L1" VARCHAR2(255 CHAR), 
    "L1_DESC" VARCHAR2(255 CHAR), 
    "L2" VARCHAR2(255 CHAR), 
    "L2_DESC" VARCHAR2(255 CHAR), 
    "L3" VARCHAR2(255 CHAR), 
    "L3_DESC" VARCHAR2(255 CHAR), 
    "L4" VARCHAR2(255 CHAR), 
    "L4_DESC" VARCHAR2(255 CHAR), 
    "L5" VARCHAR2(255 CHAR), 
    "L5_DESC" VARCHAR2(255 CHAR), 
    "L6" VARCHAR2(255 CHAR), 
    "L6_DESC" VARCHAR2(255 CHAR), 
    "L7" VARCHAR2(255 CHAR), 
    "L7_DESC" VARCHAR2(255 CHAR), 
    "L8" VARCHAR2(255 CHAR), 
    "L8_DESC" VARCHAR2(255 CHAR), 
    "L9" VARCHAR2(255 CHAR), 
    "L9_DESC" VARCHAR2(255 CHAR), 
    "L10" VARCHAR2(255 CHAR), 
    "L10_DESC" VARCHAR2(255 CHAR), 
    "L11" VARCHAR2(255 CHAR), 
    "L11_DESC" VARCHAR2(255 CHAR), 
    "L12" VARCHAR2(255 CHAR), 
    "L12_DESC" VARCHAR2(255 CHAR), 
    "L13" VARCHAR2(255 CHAR), 
    "L13_DESC" VARCHAR2(255 CHAR), 
    "L14" VARCHAR2(255 CHAR), 
    "L14_DESC" VARCHAR2(255 CHAR), 
    "L15" VARCHAR2(255 CHAR), 
    "L15_DESC" VARCHAR2(255 CHAR), 
    "OBID" VARCHAR2(255 CHAR), 
    "OBDESC" VARCHAR2(255 CHAR), 
    "MATTYPE" VARCHAR2(255 CHAR), 
    "NUMOF" VARCHAR2(255 CHAR), 
    "UOM" VARCHAR2(255 CHAR), 
    "OBTYPE" VARCHAR2(255 CHAR), 
    "PREVOBJNUM" VARCHAR2(255 CHAR), 
    "PARENTID" NUMBER(10,0), 
    "POSITION" NUMBER(10,0), 
    "LEVEL_" NUMBER(10,0) 
    ) SEGMENT CREATION IMMEDIATE 
    PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
NOCOMPRESS LOGGING 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 
    BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 
    TABLESPACE "AMS_DATA" ; 
-------------------------------------------------------- 
-- DDL for Index CONVERTED_PK 
-------------------------------------------------------- 

    CREATE UNIQUE INDEX "AMS"."CONVERTED_PK" ON "AMS"."CONVERTED" ("ID") 
    PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 
    BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 
    TABLESPACE "AMS_DATA" ; 
-------------------------------------------------------- 
-- Constraints for Table CONVERTED 
-------------------------------------------------------- 

    ALTER TABLE "AMS"."CONVERTED" ADD CONSTRAINT "CONVERTED_PK" PRIMARY KEY ("ID") 
    USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 
    BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 
    TABLESPACE "AMS_DATA" ENABLE; 
    alter table "AMS"."CONVERTED" modify ("ID" not null enable); 

這裏代替

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 
Plan hash value: 1448708152                                                                     

-------------------------------------------------------------------------------------------                                                     
| Id | Operation      | Name  | Rows | Bytes | Cost (%CPU)| Time  |                                                     
-------------------------------------------------------------------------------------------                                                     
| 0 | UPDATE STATEMENT    |   | 1053K| 31M| 4296K (25)| 05:59:18 |                                                     
| 1 | UPDATE      | CONVERTED |  |  |   |   |                                                     
| 2 | TABLE ACCESS FULL   | CONVERTED | 1053K| 31M| 84276 (1)| 00:07:03 |                                                     
| 3 | SORT AGGREGATE    |   |  1 | 17 |   |   |                                                     
| 4 | FIRST ROW     |   |  1 | 17 |  3 (0)| 00:00:01 |                                                     
|* 5 |  INDEX RANGE SCAN (MIN/MAX)| INDEX1 |  1 | 17 |  3 (0)| 00:00:01 |                                                     
-------------------------------------------------------------------------------------------                                                     

Predicate Information (identified by operation id):                                                               
---------------------------------------------------                                                               

    5 - access("T2"."OBID"=:B1 AND "T2"."ID"<:B2)                                                                

17 rows selected 
+0

讓我們來看看執行計劃從DBMS_XPLAN.DISPLAY請和DDL的表和翻新 –

+0

信息添加任何索引。歡呼 – totalitarian

+0

OBID有多少個唯一值? –

回答

1

我將開始與該指數xplan (OBID,ID)上的索引,因爲它會避免您的解釋計劃的ID 4上的表訪問。

現有查詢的大部分成本來自嵌套循環的1053K次執行,其中每次循環執行的成本爲547.其中547次用於使用索引訪問表,525次用於訪問表。必須訪問該表才能找到指定OBID的行,其ID小於正在更新的行的ID。通過在索引中包含ID,您可以在不需要訪問表的情況下執行子查詢,從而消除了每個嵌套循環執行525次的成本。

查看帶有該索引的執行計劃會很有意思。訪問索引的成本現在可能高於當前索引所引用的22,但嵌套循環的總體成本將大大降低。

編輯:啊,嵌套循環執行現在非常有效。優化器不僅識別所有候選行,然後對它們進行排序以找到最大ID,它通過直接掃描索引來查找最大ID。尼斯。

+0

是每行都需要更新 – totalitarian

+0

該索引似乎已經修復了它。它需要幾秒鐘來完成更新。你能否向我解釋究竟爲什麼。當談到優化時,我有些不高興 – totalitarian

+0

在問題中添加新的xplan – totalitarian

0

我會建議使用,結合一些先進的技術,如BULK一個PL/SQL程序COLLECTFORALL報表和並行執行(http://www.oracle-base.com/articles/11g/dbms_parallel_execute_11gR2.php將向您展示如何實現這樣的解決方案)。

Cyryl

+0

PL/SQL方法幾乎毫無例外地比純SQL方法慢。每個數據讀取或寫入都使用SQL進行,而其他任何操作都是開銷。 –