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

 更新时间:2026年04月02日 08:34:46   作者:Funky_oaNiu  
本文主要讲述如何进行Oracle表的大批量更新,包括确定更新范围、使用索引避免全表扫描、清理旧数据、估算更新时长、分批次更新以降低风险、处理更新失败、排除风险、数据备份与恢复、选择合适的时间进行更新、数据验证,并强调了整个过程的重要性

前言

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

一、执行范围

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

表名数据量字段(类型)最大长度
T_ORDER120WORDER_XML(CLOB)180w
T_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大批量数据更新的资料请关注脚本之家其它相关文章!

相关文章

  • Oracle执行Update语句的几种方式

    Oracle执行Update语句的几种方式

    这篇文章介绍了Oracle执行Update语句的几种方式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • Oracle控制文件损坏的恢复方案

    Oracle控制文件损坏的恢复方案

    本文介绍了将表空间TS_HX_SB_IDX、IDX_SSD_HX中的索引分批迁移至TS_SSD_IDX的流程及脚本编写,预计用4个晚上完成,无需业务停机,并详细说明了迁移前准备、脚本编写及迁移后的检查方法,需要的朋友可以参考下
    2025-10-10
  • Oracle别名使用要点小结

    Oracle别名使用要点小结

    在Oracle中别名也可以在列名和表名中进行,进行别名处理是为了给列或表一个临时项,下面这篇文章主要给大家介绍了关于Oracle别名使用的一些要点小结,需要的朋友可以参考下
    2022-04-04
  • oracle数据库优化辅助SQL语句

    oracle数据库优化辅助SQL语句

    这篇文章主要介绍了oracle数据库优化辅助SQL语句,需要的朋友可以参考下
    2015-10-10
  • Oracle生成单据编号存储过程的实例代码

    Oracle生成单据编号存储过程的实例代码

    Oracle生成单据编号存储过程,在做订单类似的系统都可能会存在订单编号不重复,或是流水号按日,按年,按月进行重新编号。下面给大家分享oracle生成单据编号存储过程,需要的的朋友参考下吧
    2017-04-04
  • oracle中merge into用法及实例解析

    oracle中merge into用法及实例解析

    这篇文章主要介绍了oracle中merge into用法及实例解析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • oracle学习笔记(三)

    oracle学习笔记(三)

    最近需要用的oracle,所以大家好好的学习下基础并整理下资料,希望能帮助到需要的朋友。
    2011-12-12
  • Oracle分区表超详细讲解(Oracle Partitioned Tables)

    Oracle分区表超详细讲解(Oracle Partitioned Tables)

    这篇文章主要给大家介绍了挂不同意Oracle分区表超详细讲解(Oracle Partitioned Tables)的相关资料,ORACLE的分区是一种处理超大型表、索引等的技术,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • Oracle分页查询性能优化代码详解

    Oracle分页查询性能优化代码详解

    这篇文章主要介绍了Oracle分页查询性能优化代码详解,简述了进行分页查询性能优化的原因,具有一定参考价值,需要的朋友可以了解下。
    2017-09-09
  • Oracle查询今天、昨天、本周、上周、本月、上月数据方式

    Oracle查询今天、昨天、本周、上周、本月、上月数据方式

    这篇文章主要介绍了Oracle查询今天、昨天、本周、上周、本月、上月数据方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07

最新评论