注册
rowid的简单应用-改进版
专栏/小周历险记/ 文章详情 /

rowid的简单应用-改进版

啊小周 2026/07/08 291 1 0
摘要 -如何利用rowid特性对大表数据进行归档呢?过去项目上使用rowid特性进行数据归档,出现一些问题,这次带来改进版。

一、 背景介绍

项目上经过一段时间运行后,表的数据增加后,性能逐步下降,因此数据归档任务成了项目上必不可少的作业,之前有介绍过rowid简单应用,在数据归档任务中得到推广,但在使用期间,会遇到几个问题,因此就几个问题,进行了脚本升级改进。

二、 问题

1、 数据溢出

image.png

这里rowid值太大原因在于它是分区表,分区表rowid值是按分区逻辑递增的,不同分区它不是递增的,因此应该要在分区子表利用递增特性求最大rowid和最小rowid,如下图所示
image.png
从上面可以知道,需要在分区子表使用rowid递增特性
另外如果该表经常删除插入,rowid是会膨胀的,可以做个实验
image.png
原先rowid从1排到10,删除id=3,即rowid=3
image.png
此时rowid情况
image.png
Rowid=3空缺没有补上,新增的数据继续递增,因此会出现rowid膨胀到很大的情况。

2、 性能问题

(1) 每批可操作的数据不均匀

过去做法:
image.png
前面提到rowid会出现空缺,此时如果根据(rowid最大-rowid最小值)/(10w),然后按照求出来的循环次数去操作数据,假设rowid:1-10w中实际上只保留100条数据,其他rowid空缺的,那么这批数据操作就100条,那么循环次数就相对实际上变多了。

(2) 系统视图dba_tab_partitions

过去分区表归档会使用dba_tab_partitions求得分区子表名字,如果数据库分区表较多此时该视图使用上会显得笨重。

(3) Rowid聚集索引特性使用

当求最大rowid和最小rowid时,此时做法是:
image.png
如果update_time没有索引会导致全表扫。

三、 解决

1、 数据溢出问题

首先应该要区分普通表和分区表
image.png
新版的数据归档脚本做了普通表和分区表的判断
然后把每批操作的数据量不受rowid有空位影响
image.png
按分区表操作来简述操作逻辑:
根据归档条件计算每个子分区归档的数据量和最小rowid值,数据量是用来计算循环次数,因为存储过程确定循环的每批数据量(10w),count/10w就是我们循环次数,
而每次临时表会记录10w个rowid,是这样算的
image.png
以上是整个循环体的循环逻辑,
第一步:
先根据传入的归档条件计算每个子分区表数据量,最小rowid(循环开始的rowid)
第二步:
确定循环次数,数据量/每批操作数据量(10w)
第三步:
进入循环,计算每批操作rowid的最大值(尾巴rowid)
第四步:
操作实际的数据,
第五步:
进入下一次循环,重复第三步
第六步:
分区子表完成一个,进行下一个分区子表归档,执行第二步

2、 性能问题

(1) 每批可操作的数据得到控制

前面数据溢出第二个问题解决就是这个问题的答案,不予赘述。

(2) 替换系统视图

image.png

(3) Rowid聚集索引特性使用

image.png

四、 总结

(1)以上的数据归档方式不用考虑分区表和非分区表方式,并且都是统一用到rowid特性解决归档时的性能问题,使用起来比之前便捷。
(2)重建表更换表名方式会比insert方式和delete方式更加高效。
(3)重建表更换表名方式是新建的表,数据紧凑,对于数据膨胀问题有所缓解。(即解决一些表经过频繁的update和delete操作后出现数据空洞)。
(4)Insert和delete方式,优点是可以不需要切换表名对数据进行归档,并且适合一些原本没有频繁update和delete操作的表(数据膨胀不明显)

五、 附件脚本

1、重建表更换表名方式

数据归档-完整步骤.txt

2、insert和delete方式

数据归档-完整步骤2.txt

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服