项目上经过一段时间运行后,表的数据增加后,性能逐步下降,因此数据归档任务成了项目上必不可少的作业,之前有介绍过rowid简单应用,在数据归档任务中得到推广,但在使用期间,会遇到几个问题,因此就几个问题,进行了脚本升级改进。
这里rowid值太大原因在于它是分区表,分区表rowid值是按分区逻辑递增的,不同分区它不是递增的,因此应该要在分区子表利用递增特性求最大rowid和最小rowid,如下图所示
从上面可以知道,需要在分区子表使用rowid递增特性
另外如果该表经常删除插入,rowid是会膨胀的,可以做个实验
原先rowid从1排到10,删除id=3,即rowid=3
此时rowid情况
Rowid=3空缺没有补上,新增的数据继续递增,因此会出现rowid膨胀到很大的情况。
过去做法:
前面提到rowid会出现空缺,此时如果根据(rowid最大-rowid最小值)/(10w),然后按照求出来的循环次数去操作数据,假设rowid:1-10w中实际上只保留100条数据,其他rowid空缺的,那么这批数据操作就100条,那么循环次数就相对实际上变多了。
过去分区表归档会使用dba_tab_partitions求得分区子表名字,如果数据库分区表较多此时该视图使用上会显得笨重。
当求最大rowid和最小rowid时,此时做法是:
如果update_time没有索引会导致全表扫。
首先应该要区分普通表和分区表
新版的数据归档脚本做了普通表和分区表的判断
然后把每批操作的数据量不受rowid有空位影响
按分区表操作来简述操作逻辑:
根据归档条件计算每个子分区归档的数据量和最小rowid值,数据量是用来计算循环次数,因为存储过程确定循环的每批数据量(10w),count/10w就是我们循环次数,
而每次临时表会记录10w个rowid,是这样算的
以上是整个循环体的循环逻辑,
第一步:
先根据传入的归档条件计算每个子分区表数据量,最小rowid(循环开始的rowid)
第二步:
确定循环次数,数据量/每批操作数据量(10w)
第三步:
进入循环,计算每批操作rowid的最大值(尾巴rowid)
第四步:
操作实际的数据,
第五步:
进入下一次循环,重复第三步
第六步:
分区子表完成一个,进行下一个分区子表归档,执行第二步
前面数据溢出第二个问题解决就是这个问题的答案,不予赘述。
(1)以上的数据归档方式不用考虑分区表和非分区表方式,并且都是统一用到rowid特性解决归档时的性能问题,使用起来比之前便捷。
(2)重建表更换表名方式会比insert方式和delete方式更加高效。
(3)重建表更换表名方式是新建的表,数据紧凑,对于数据膨胀问题有所缓解。(即解决一些表经过频繁的update和delete操作后出现数据空洞)。
(4)Insert和delete方式,优点是可以不需要切换表名对数据进行归档,并且适合一些原本没有频繁update和delete操作的表(数据膨胀不明显)
文章
阅读量
获赞
