2016-07-29 492 views
1

有主表键(Enterpriseid, Ownertype, Ownerid, Itemtype, Itemid)的表EFORMDYNAMICFIELDINSTANCEOracle Update更新主键列需要很长时间

为了将主键更改为单列,即EDFI_ID我们想要将此EDFI_ID更新为以7000000为增量值。

这张表几乎没有50000条记录需要10小时更新。 这是我的表认定中:

ENTERPRISEID NOT NULL NUMBER(10), 
OWNERTYPE NOT NULL VARCHAR2(60), 
OWNERID  NOT NULL NUMBER(10), 
ITEMTYPE  NOT NULL VARCHAR2(60), 
ITEMID  NOT NULL NUMBER(10), 
EDFI_ID  NOT NULL NUMBER(10), 
FIELD1    VARCHAR2(2000), 
FIELD2    VARCHAR2(2000), 
... 
FIELD199    VARCHAR2(2000), 
FIELD200    VARCHAR2(2000) 

早些时候,我们曾(ENTERPRISEID, OWNERTYPE, OWNERID, ITEMTYPE, ITEMID)作为主键。

Now EDFI_ID是我的主键列,我们想用(rownumber + 7000000)来更新这个主键。该表约有50000条记录,EDFI_ID应更新为7000000,7000001,7000002 .... 7050000。

请建议一个UPDATE声明,这将花费更少的时间。截至目前我的上述UPDATE需要10个小时。

+0

什么的WHERE存在意义呢?你想更新每一行,对吗? –

+0

使用CATS [cats](http://www.dba-oracle.com/t_create_table_select_ctas.htm)创建新表 –

+0

此语句具有O(N^2)性能。使用合并语句,在using子句中计算新的edfi_id,并在“matched”子句中使用新计算的edfi_id,并跳过“not matched”子句。这会让你回到O(N)的表现。 –

回答

0

我的猜测是你的问题是重复执行你的子查询。我甚至不确定第二个(在WHERE EXISTS里面)是否有用。

  1. 删除WHERE EXISTS - 这将消除一半的努力。如果这样做没有帮助,那么...
  2. 创建一个临时映射表,它保存所有现有的主键值以及新的PK值。在您的五个PK栏中创建一个唯一的索引。然后使用映射表中的子查询

只是为了阐述我的第二个建议:

CREATE TABLE temp_pk_mapping AS 
(SELECT 
    enterpriseid 
,ownertype 
,ownerid 
,itemtype 
,itemid 
,rownum + 70000  new_pk 
FROM 
    (SELECT DISTINCT 
    enterpriseid 
    ,ownertype 
    ,ownerid 
    ,itemtype 
    ,itemid 
    FROM 
    eformdynamicfieldinstance 
    ) 
) 
; 

CREATE UNIQUE INDEX temp_pk_mapping_u1 ON temp_pk_mapping 
(enterpriseid 
,ownertype 
,ownerid 
,itemtype 
,itemid 
) 
; 

UPDATE eformdynamicfieldinstance edfi 
SET edfi.edfi_id = 
(SELECT new_pk 
    FROM temp_pk_mapping map 
    WHERE edfi.enterpriseid = map.enterpriseid 
    AND edfi.ownertype = map.ownertype 
    AND edfi.ownerid = map.ownerid 
    AND edfi.itemtype = map.itemtype 
    AND edfi.itemid = map.itemid 
) 
; 
+0

很好的解决方案将尝试 – suraj1287

+0

注意我刚刚在表创建脚本中添加了一个别名new_pk –