mysql 使用临时表+存储过程删除大表中的大量数据

Posted by Vincent on August 9, 2010

当一个表mysql的表成长到1000w以上,然后需要更加某些条件去删除其中的几百万数据的时候,如果直接delete将是一件极其痛苦的事情。 时间长是必然的,而且堵塞了正常应用的更新等操作,很有可能的导致数据库hang住和应用的崩溃

--常用的方法,如果表是1000w,符合删除条件的数据是400w的话,那时间一般会超过半个小时乃至更长
delete from xf_user_info where status=2 and date(gmt_create) < '2010-07-01';

----------使用类似于oracle常用的方式来完成,如果有更好的方法,不吝赐教

--写个临时表和存储过程,来完成
--创建临时表
create table tmp_xf_id_del  as
select id from xf_user_info where status=2 and gmt_create< '2010-07-01';

delimiter // --使用//带代替;,这个符号可以自己定义
delimiter ;  --换回;

set autocommit =0;  --设置为非自动提交,脚本中定义为100条提交一次

------华丽的分割线---------

--创建存储过程
CREATE PROCEDURE sp_xf_del_test()
begin
declare v_exit int default 0;
declare v_id bigint;
declare i int default 0;
declare c_ids cursor for select id from tmp_xf_id_del;
declare  continue handler for not found set v_exit=1;
open c_ids;
repeat
fetch c_ids into v_id;
delete from xf_user_info where id  = v_id;
set i=i+1;
if mod(i,100)=0 then commit;
end if;
until v_exit=1
end repeat;
close c_ids;
commit;
end;
//

-------------
--调用存储过程
call sp_xf_del_test()//

--
我的估算: 用100条COMMIT一次的方式比单条提交的方式效率高40%


This work is licensed under a CC A-S 4.0 International License.