为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】:DM7
【操作系统】:凝思80
【CPU】:X86
【问题描述】*:表里有3000万数据,根据时间过滤查询删除很慢,想用sql每次删除最早的1万行,循环2900次
按你的想法,可以试试用游标根据rowid批量删除看看
declare
type type_rowid
is
table of rowid;
type ref_cursor is ref cursor;
v_rowid type_rowid := new type_rowid();
cur ref_cursor;
begin
open cur for
select a.rowid from tb1 a where a.date1<sysdate-30;
loop
fetch cur bulk collect into v_rowid limit 10000;
for i in 1 .. v_rowid.count
loop
delete tb1 a where a.rowid = v_rowid(i);
end loop;
commit;
exit when cur%notfound;
end loop;
v_rowid.delete();
close cur;
end;
可以通过shell脚本调sql,进行删除。两种命令看看你的版本支持吗,第一种是用limit,第二种是用rowid。申请先手动删10条试一下:
(1)delete from sch.tab1 limit 10;
(2)delete from sch.tab1 where rowid<=(select min(rowid)+10 from sch.tab1);
如果可行,编写以下sheel脚本,sh del.sh即可
vim del.sh
先创建个同构表做备份,把最近1个月的数据写进去,然后把原表TRUNCATE掉,再把备份表里这一个月的数据写回到原表里,类似于:
--备份出最近一个月的数据 CREATE TABLE 原表名_BAK_20241127 AS SELECT * FROM 原表名 WHERE 日期字段名 >= TRUNC(SYSDATE,'MM'); --清空原表 TRUNCATE TABLE 原表名; --回写最近一个月的备份数据 INSERT INTO 原表名 SELECT * FROM 原表名_BAK_20241127;
注意,数据量比较大,且使用TRUNCATE无法回退,所以如果是生产库,务必把原表完整备份,以避免因错误操作造成损失。