优化Oracle Update Select

时间:2014-02-05 08:10:57

标签: oracle

我的查询如下

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);

以下是带有索引的xplan

  ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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  

2 个答案:

答案 0 :(得分:1)

我会从(OBID,ID)上的索引开始,因为它会避免解释计划的ID 4上的表访问。

现有查询的大部分成本来自嵌套循环的1053K执行,其中每个循环执行成本547.在547中,22是使用索引访问表而525是用于访问表。必须访问该表才能查找指定OBID的行,其ID小于要更新的​​行的ID。通过在索引中包含ID,您可以执行子查询而无需访问该表,从而消除了每个嵌套循环执行525的成本。

查看具有该索引的执行计划会很有趣。现在访问索引的成本可能高于当前索引引用的22,但嵌套循环的总体成本将大大降低。

编辑:啊,嵌套循环执行现在非常有效。优化器不仅识别所有候选行,然后对它们进行排序以查找最大ID,它通过直接扫描索引来查找最大ID。好的。

答案 1 :(得分:0)

我建议使用PL / SQL程序,它结合了一些高级技术,如 BULK COLLECT FORALL 语句和 PARALLEL 执行({{ 3}}将向您展示如何实施此类解决方案)。

Cyryl