业务人员要求在一个表上重新创建主键列。表中已有的数据存在重复,需要对每一行数据生成唯一值作为主键。
首先想到的方法创建一个临时表,通过 rowid 与原表建立关联,然后根据临时表对原表进行更新。
临时表建表语句为
create table met_ipm_order_tmp asselect ROWIDTOCHAR(t.rowid) as primary_key from met_ipm_order t;
更新语句为
UPDATE met_ipm_order tSET t.id =(SELECT t.primary_keyFROM met_ipm_order_tmp pWHERE t.rowid = p.primary_key)WHERE EXISTS (SELECT 1 FROM met_ipm_order_tmp pWHERE t.rowid = p.primary_key);
因为业务只要求主键列数据唯一,对内容没有要求,所以直接使用 rowid 作为主键。如果想使用数字作为主键,可以使用 rownum 作为主键。
在测试库执行时发现,表的数据量非常大,记录数有5千万条,没法通过一条 update 对全表进行更新。如果在实际业务中,这种更新将无法实施,因为表处于活跃状态,并且读写非常频繁,大数据量更新,在业务高峰时将造成锁表。
于是放弃 update 方案,尝试使用小步更新方式来写入数据。最终在测试库中的尝试的方案是使用 ETL 工具 Spoon ,辅助临时表对目标表执行 update。ETL 工具有小批量更新的机制,不会造成长时间锁表,但执行时间会拖的比较长。

最后一个方案是在CSDN上查到的,基于 sequence 更新,也是全表update。我在测试库上试了一下,执行速度要比临时表方式要快一点儿。
-- 增加主键列alter table met_ipm_order add pk_id number(38);create sequence MET_IPM_SEQ_IDminvalue 1maxvalue 999999999start with 1;Update met_ipm_order set pk_id=MET_IPM_SEQ_ID.nextval;commit;
参考:
https://blog.csdn.net/lexang1/article/details/73900034
文章转载自生有可恋,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




