Oracle大批量数据更新的避坑指南与关键原则

来源:这里教程网 时间:2026-04-02 09:11:29 作者:
前言一、执行范围二、索引三、旧数据/脏数据清理四、更新时长估算五、更新方式1.分批次更新2.分批次事务提交3.分页查询4.暂停更新功能六、更新失败处理1.日志记录2.事务回滚方式七、风险排除1.表空间风险2.索引风险3.内存风险4.日期风险八、数据备份九、数据更新时机十、数据恢复十一、数据验证十二、庆祝一下

前言

本文旨在提供完善的总体思路,避免遗漏或出现严重问题,具体Oracle命令太过繁琐不在此陈列。

一、执行范围

首先我们要确定更新哪些表,每张表有多少待更新的数据量,每张表更新哪个字段,每个字段的类型是什么,字段最大长度,字段是否有索引如下所示:

表名数据量字段(类型)最大长度T_ORDER120WORDER_XML(CLOB)180wT_MESSAGE240WMSG_CONTENT(CLOB)59w

二、索引

由于表数据量比较大,select和update语句的where条件要使用主键或者有索引的列,有效避免全表扫描,减少锁表时间。

三、旧数据/脏数据清理

先检查一下表里和业务代码,是否可以清理旧数据/脏数据,如果可以,说不定本来百万级的表可以瘦身到一两万的数据量,大大减轻批量更新的压力。
再检查一下脏数据会不会对你的更新逻辑产生影响。

四、更新时长估算

可以在本地或测试环境造模拟数据,模拟生产环境真实的更新数据量,以及每条更新的数据长度大小,估算出一个语句更新时长,评估时长是否可以接受;
若全部数据更新时间太长不能接受,可以考虑是否可以先根据时间更新近期数据,或本次只更新部分表数据,更新完成后,后续再持续更新。

五、更新方式

1.分批次更新

如果单条数据占空间比较大,那么单批次量就要小一些,像我上面列举的CLOB类型的大字段,每批次100~500条合理(根据服务器配置决定);如果单条空间小,可以适当增加每批次大小。

2.分批次事务提交

不要一条一条提交事务,也不要几百万才提交一次事务,这里建议每次提交事务的量和上面批次的量一样既可。

3.分页查询

如果你是在Java中进行更新,记得使用分页查询,不要把几百万条数据一下查询到内存里,最好手写分页,框架的分页容易出bug。

4.暂停更新功能

比如要更新300w条数据,可能会出现更新到150w条数据时发现之前更新失败的数据,需要暂停当前更新,处理好失败数据之后再继续更新,需要做更新暂停功能,这样就不用等待全部数据跑完才能处理异常数据了,从程序设计而言是一个非常好的灵活性设计。

六、更新失败处理

1.日志记录

要有完善的日志记录,例如总数据量、每批更新数量、每批更新成功数量、每批更新失败数量、更新失败的数据ID、失败原因

2.事务回滚方式

要根据自身业务场景,考虑好是一条失败不影响继续执行,还是一条失败整批失败,还是一条失败整表失败等等

七、风险排除

1.表空间风险

如果你是更新clob字段,并且现有表空间剩余不足的情况下,就要谨慎一些,因为clob字段在update的时候需要将新数据和旧数据同时存储(碎片化),但是并不是说比如旧数据有1G,那就需要2G,Oracle有自动回收机制,但是如果你的clob字段是BASICFILE,就需要处理一部分就手动执行SHRINK SPACE命令来整理碎片,释放空间。如果clob字段是SECUREFILE,Oracle的自动回收更积极,但是仍有风险,保险起见还是要对表空间进行扩容。

2.索引风险

如果你的update语句的where条件没有索引,可能会导致update执行过慢,这个过程是锁表的,如果你的业务不依赖这张表,那没事,如果依赖,可能会导致业务停滞。

3.内存风险

如果你是在java程序中去批量执行update语句,要注意大字段在Java中的处理,小心OOM内存溢出。

4.日期风险

如果你是通过日期去分批更新,注意不同表的同一日期范围的数据量是不同的,比如我 日期范围是近一个月,A表可能只有3000条数据,B表会有50万条数据,这种情况要考虑到。

八、数据备份

最好用expdb数据泵方式导出,如果不行就使用exp命令,如果exp命令也使用不了,就使用下面的sql库内备份,但是库内备份要注意备份完之后的表空间容量是否不足。

CREATE TABLE T_ORDER_20260401_BAK AS SELECT * FROM T_ORDER;

九、数据更新时机

大批量的数据更新需要避开业务高峰期,在系统使用率低,数据库流量小的时候进行。

十、数据恢复

要提前写好数据恢复的脚本/命令,不能等出了问题想恢复的时候现写,尽量减少数据变化产生的差异,下面列一条库内备份表的恢复命令(比普通update快非常多)。

MERGE INTO T_ORDER b USING T_ORDER_BAK a ON (b.id = a.id) WHEN MATCHED THEN UPDATE SET b.待恢复字段 = a.待恢复字段;

十一、数据验证

1、数据验证的时机要包括执行前验证、执行中验证、执行后验证;
2、需要提前写好数据验证的SQL,最好自动化高一点,不要一条一条执行然后在肉眼比对数据的那种SQL,等更新执行完成之后,达到一键验证的效果;
3、数据验证的SQL尽量考虑全面的一些,针对不同的业务场景进行验证。

十二、庆祝一下

如果你按照本文的方案完美完成了重要数据更新,那可以长舒一口气,然后夸夸自己了!

以上就是Oracle大批量数据更新的避坑指南与关键原则的详细内容,更多关于Oracle大批量数据更新的资料请关注其它相关文章!

相关推荐

热文推荐