DELETE⼤批量数据的性能优化
⼤批量数据的性能优化
问题的提出:
⼀个表有上千万的数据,欲从该表中删除部分数据;
在线⽤的⽣产库,不能影响⽣产;
该表有四个索引,删除的sql语句⽤到了索引;
正常业务不能停⽌-不能disable约束,也不能临时不⽤索引;
问题的解决:
这个问题中应该重点考虑的问题是这个系统是⽣产系统,不能离线,所以只能是根据情况考虑⼀些在线的删除⽅式。
批量更新sql语句1、 如果是定期清楚历史数据的话,可以考虑⽤partition的⽅式,采⽤分区⽅式是其优点之⼀,能够使⽤其易于管理的⼀个⽅⾯,在这⾥是不是
应该考虑分区时候是采⽤我们需要删除的数据为分区的原则。
2、 增⼤回滚段,通过设置使⽤这个回滚段,来提⾼系统的删除操作的速度,但是对于Oracle9i以后的系统来说,由于使⽤了⾃动管理回滚段
的情况,如何进⾏回滚段的设置。
3、 增⼤redo log在线⽂件的⼤⼩,以便减少checkpoint的执⾏频率,增⼤buffer来提⾼删除的速度。这个主要⽬的是减少系
统checkpoint的次数,尽量少减少磁盘IO的次数,能够在数据缓存上执⾏的尽量在内存中实现。
4、 使⽤rowid来删除数据。
1.根据⽤户所提需求过滤需要删除的源数据,create 临时表 as select rowid rid from 需要删除的表 where 删除条件。
2.使⽤pl/sql block来删除数据,这样能保证及时递交,防⽌lock过多的⾏导致系统负载增加。这⾥需要注意commit的频率,⼀般为更新100条记录commit⼀次。
create table temp_del表名_040803 as
select rowid rid from 要删除的表 where ......
declare
execrow number;
begin
execrow:=1;
for i in 1..需要更新的记录数/100(取整) loop
delete 要删除的表
where rowid in(select rid from temp_del表名_040803 where rownum<100);
delete from temp_del表名_040803 where rownum<100;
commit;
end loop;
end;
/
记得再建⼀张临时表保存要删除的内容已备回滚。这样根据rowid来删除的话效率会⽐较⾼。
5、 在Oracle 9i之后,可以考虑使⽤bulk delete的新功能。(这个没有⾼清楚是什么东西)
6、 如果在不是⽣产库的时候,如果索引没有在删除时使⽤的情况下,(如果在删除的语句中使⽤了索引得话,这样能够提⾼删除的速度)可
以将索引删除,等执⾏完删除语句的时候,可以考虑重建索引,因为删除索引上的数据的时候也是需要时间和系统消耗的,这时候需要看看你所要删除的数据量的多少,如果数据量相对整个表⽐较⼤的时候,可以考虑使⽤全表扫描,这样应该是更快的⽅式,如果⽐率⽐较⼩的时候,使⽤索引到rowid来删除应该是⽐较好的选择。
7、 有⼈提出这样的观点:
相关问题,俺们也经常遇到,共享经验如下:
1.表分区异常重要
2.索引过多很是⿇烦
3.相关约束更是头痛(4M数据如果有N个⼦表对其参照,乖乖..)
4.表空间如过是dictionary管理,必须选择分段批量提交(俺们的数据库都被锁死了)
5.会滚、排序,⼤redo,多个arch线程,必须养成习惯,任何⼤数据量批量操作,都不可少。
6.临时表(在临时表空间上)⽤于查询果然较快。
7.引⽤偶像的话“Delete就是慢,就是慢,就是慢.”,没办法。
最后还是想说,象这样的⼯作只有考虑应⽤的特征,才会到⽐较好的⽅法(俺觉得)
问题:表空间如过是dictionary管理,必须选择分段批量提交(俺们的数据库都被锁死了),为什么是这样的?
==========================
======================
========================

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。