请教一个关于循环的问题,删除数据

jakenlian 2015-07-29 06:08:53
我有一张有数千万数据的大表,现在想删掉一些没用的历史数据,如果用常规删法的话,会很慢,如:
delete from table_a t where t.id<5000000;
我的表有5个字段,其中id有索引。
删了两个小时,也没有完成。

考虑了一下,想用一个过程,让服务器自己空闲的时候,自己去删:

create or replace procedure self_procedure is
begin
for v in 4805000000 .. 4810000000 loop
delete from SYS2SYN_DATA_DETAIL t where t.master_id = v;
commit;
end loop;
end;

这样没似乎可以实现,但是每次只删除一条,不知道会删到什么时候,而且磁盘操作似乎有些频繁。
于是想一次多删除一些:

create or replace procedure self_procedure_muti is
begin
for v in 4805000000 .. 4810000000 loop
delete from SYS2SYN_DATA_DETAIL t where t.master_id < v;
v:=v+1000;
commit;
end loop;
end;

可是这个过程报错了,“表达式v不能用作赋值目标”。

请问,各位有什么好的办法没有?
...全文
237 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
滇中倦客 2015-07-31
  • 打赏
  • 举报
回复
使用forall,批量提交delete语句:
create or replace procedure self_del_syn_data_detail is
v number(19);
type tb_table_type is table of tmp_tab%rowtype index by binary_integer;

tb_table tb_table_type;
begin
for i in 4805000000 .. 4810000000 loop
tb_table(i).id := i;
end loop;
forall v in 1 .. tb_table.count
delete from SYS2SYN_DATA_DETAIL t where t.master_id = v + 4805000000;
commit;
end;
LongRui888 2015-07-30
  • 打赏
  • 举报
回复
引用 3 楼 jakenlian 的回复:
这样实现了: create or replace procedure self_del_syn_data_detail is v number(19); begin for v in 0 .. 5000000 loop delete from SYS2SYN_DATA_DETAIL t where t.master_id = v + 4805000000; commit; end loop; end;
一条一条删除数据是比较慢的,最好是批量化删除,一次删除个1w条左右,速度还是蛮快的。 下面版主的方法很好,而且很简单,通过rownum可以起到限制 每次只删除几千条数据。
xu176032 2015-07-30
  • 打赏
  • 举报
回复
上一阵刚做了一个类似这种删除的优化,建议游标里查询一下rowid,然后配合上order by ,循环里面根据这个rowid去删除,速度会快很多,内存占用也可以,我们试过超千万级的数据~
chengccy 2015-07-30
  • 打赏
  • 举报
回复
如果表没有外键,在非占用时候可以用create+rename
小灰狼W 2015-07-29
  • 打赏
  • 举报
回复
其实最简单的:

begin

loop
delete from SYS2SYN_DATA_DETAIL where t.id<5000000 and rownum<=5000;
exit when sql%notfound;
commit;
end loop;
end;
/

rownum<=后面就是一次删的行数。id<5000000的全部删完,跳出循环
jakenlian 2015-07-29
  • 打赏
  • 举报
回复
这样实现了: create or replace procedure self_del_syn_data_detail is v number(19); begin for v in 0 .. 5000000 loop delete from SYS2SYN_DATA_DETAIL t where t.master_id = v + 4805000000; commit; end loop; end;
jakenlian 2015-07-29
  • 打赏
  • 举报
回复
在FOR循环中可能会遇到ORA-01426,主要是由于起始值或者结束值超过了2147483647,默认情况下
FOR 循环的数值需要 在-2147483648 到 2147483647之间,否则就会报错。

二楼的问题解决了:
http://blog.chinaunix.net/uid-22948773-id-3047969.html
jakenlian 2015-07-29
  • 打赏
  • 举报
回复
补充一句,我的这个过程,在建的时候没有报错。但是执行的时候,报错“ora-01426数字溢出”

3,491

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧