ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Delete大批量数据的方法

Delete大批量数据的方法

Linux操作系统 作者:lyh1987330 时间:2016-10-18 17:00:33 0 删除 编辑

前些日子,开发让我删除某个表08年以前的数据(delete from t1 where to_char(time,'yyyymmdd')<'20080101';)。首先,我查了下需要删除的行数,

大约有140多万行,开发这时告诉我,他删除时报ORA-01555,这个当然很正常,回滚段设的不够大。

后来,我查了相关资料,基本有两种方法

第一种:可以先建一个临时表,把t1表中大于20080101的数据倒入到临时表,然后truncate掉t1表,然后再把临时表的数据插入t1表。


测试过程如下:
SQL> conn scott/tiger

已连接。

SQL> create table t1 as select * from emp;

表已创建。

SQL> insert into t1 select * from t1;

已创建14行。

SQL> /

已创建28行。

SQL> /

已创建56行。

SQL> /

已创建112行。

SQL> /

已创建224行。

SQL> /

已创建448行。

SQL> /

已创建896行。

SQL> /

已创建1792行。

SQL> /

已创建3584行。

SQL> /

已创建7168行。

SQL> /

已创建14336行。

SQL> /

已创建28672行。

SQL> /

已创建57344行。

SQL> /

已创建114688行。

SQL> /

已创建229376行。

SQL> /

已创建458752行。

SQL> /

已创建917504行。

SQL> select count(*) From t1;

COUNT(*)

----------

1835008

SQL> select distinct empno from t1;

EMPNO

----------

7782

7839

7844

7698

7521

7902

7566

7654

7788

7934

7499

EMPNO

----------

7876

7369

7900

已选择14行。

SQL> update t1 set empno=6666 where empno<7900;

已更新1441792行。

以上步骤构造实验表,共183多万行,其中empno小于7900的有144多万行,

打算删除这144多万行

SQL> select distinct empno from t1 order by empno;

EMPNO

----------

6666

7900

7902

7934

SQL> create table tmp_t1 as select * from t1 where empno>6666;

表已创建。

将empno不是6666的数据导入到临时表tmp_t1中

SQL> select count(*) From tmp_t1;

COUNT(*)

----------

393216

SQL> select distinct empno from tmp_t1 order by empno;

EMPNO

----------

7900

7902

7934

SQL> truncate table t1;

表被截断。

将t1表截断

SQL> select count(*) From t1;

COUNT(*)

----------

0

SQL> insert into t1 select * From tmp_t1;

已创建393216行。

将保留下的数据从tmp_t1表导入到t1

SQL> select count(*) From t1;

COUNT(*)

----------

393216

SQL> select distinct empno from t1 order by empno;

EMPNO

----------

7900

7902

7934

验证结果正确

但是,这种方法不太适用于OLTP,因为每秒钟表的都有数据变化,很可能截断表时有数据插入,所以我最后用的是第二种方法。

第二种:分批删除,逐次提交。

具体测试过程如下:

SQL> create table t2 as select * from emp;

表已创建。

SQL> insert into t2 select * From t2;

已创建14行。

SQL> /

已创建28行。

SQL> /

已创建56行。

SQL> /

已创建112行。

SQL> /

已创建224行。

SQL> /

已创建448行。

SQL> /

已创建896行。

SQL> /

已创建1792行。

SQL> /

已创建3584行。

SQL> /

已创建7168行。

SQL> /

已创建14336行。

SQL> /

已创建28672行。

SQL> /

已创建57344行。

SQL> /

已创建114688行。

SQL> /

已创建229376行。

SQL> /

已创建458752行。

SQL> /

已创建917504行。

SQL> select count(*) FRom t2;

COUNT(*)

----------

1835008

以上步骤构造实验表,共183多万行

SQL> select distinct empno from t2;

EMPNO

----------

7782

7839

7844

7698

7521

7902

7566

7654

7788

7934

7499

EMPNO

----------

7876

7369

7900

已选择14行。

SQL> update t2 set empno=8888 where empno<7900;

已更新1441792行。

这样做为了便于删除t2表中的大部分行

SQL> create or replace procedure delBigTab

2 (

3 p_TableName in varchar2,

4 p_Condition in varchar2,

5 p_Count in varchar2

6 )

7 as

8 pragma autonomous_transaction;

9 n_delete number:=0;

10 begin

11 while 1=1 loop

12 EXECUTE IMMEDIATE

13 'delete from '||p_TableName||' where '||p_Condition||' and rownum <= :rn'

14 USING p_Count;

15 if SQL%NOTFOUND then

16 exit;

17 else

18 n_delete:=n_delete + SQL%ROWCOUNT;

19 end if;

20 commit;

21 end loop;

22 commit;

23 DBMS_OUTPUT.PUT_LINE('Finished!');

24 DBMS_OUTPUT.PUT_LINE('Totally '||to_char(n_delete)||' records deleted!');

25 end;

26 /

过程已创建。

SQL> set timing on

SQL> exec delBigTab('T2','EMPNO=8888','10000');

PL/SQL 过程已成功完成。

已用时间: 00: 02: 49.82

删除144多万行数据,不到3分钟

SQL> select COUNT(*) fROM t2;

COUNT(*)

----------

393216

已用时间: 00: 00: 01.12

SQL> select distinct empno from t2;

EMPNO

----------

7902

7934

7900

已用时间: 00: 00: 01.35

验证数据,已删除

相关参考文章:http://www.eygle.com/archives/2005/04/oracleoeouaeeae.html

http://www.itpub.net/viewthread.php?tid=934825&extra=&highlight=%2BAlienovo&page=1

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31403234/viewspace-2126673/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2016-10-18

  • 博文量
    2
  • 访问量
    2302