保持每个用户最后100个交易,并删除其余的

时间:2015-01-16 15:29:16

标签: mysql sql

我有一个表名tbl_tmp_trans 它包含曾经完成的每个用户交易(现在最多可达6Mil!)

我们决定在我们的数据库中每个用户只保留最后100个事务,这样我们就可以保持数据库干净 这是我提出的查询

delete  from tbl_tmp_trans 
where   trans_id in 
(
    select  trans_id 
    from 
    (
        select  trans_id 
        from    tbl_faucets_transactions 
        order   by date 
        group   by user_id 
        limit   100
    ) foo 
)
我在做错了什么?

因为在执行此操作后,我的cpu达到100%并且mysql崩溃。

提前致谢 P.S:我们的数据库是Mysql,表引擎是Innodb

P.S2:我们有大约120k和转换表有近600万记录

1 个答案:

答案 0 :(得分:0)

我有一个提案......希望它可以帮到你。

改变你的表格:

alter table tbl_tmp_trans add column todel tinyint(1);

实现存储过程以使用游标迭代表,并标记(设置todel1)应删除的记录。执行此操作的示例过程:

delimiter //
drop procedure if exists mark_old_transactions //
create procedure mark_old_transactions()
begin
    declare done int default false;
    declare tid int;
    declare uid int;
    declare last_uid int default 0;
    declare count int default 0;
    declare cur cursor for select trans_id, user_id from tbl_tmp_trans order by user_id, date desc;
    declare continue handler for not found set done = true;

    open cur;
    repeat
        fetch cur into tid, uid;
        if (!done) then
            if (uid!=last_uid) then
                set count = 0;
            end if;
            set last_uid = uid;
            set count = count + 1;
            if (count > 100) then
                update tbl_tmp_trans set todel=1 where trans_id=tid;
            end if;
        end if;
    until done
    end repeat;
    close cur;
end //

调用该过程,可能会进行一些简单的检查(从表中删除多少个事务等),并删除标记的记录。

call mark_old_transactions;
-- select count(*) from tbl_tmp_trans where todel=1;
-- select count(*) from tbl_tmp_trans;
delete from tbl_tmp_trans where todel=1;

最后,删除我们刚刚添加的列。

alter table tbl_tmp_trans drop column todel;

一些注意事项:

  • 可能你必须遍历表格的所有记录 无论如何,所以你不要用光标松动表现。
  • 如果您有大约120,000个用户和约6百万个交易,则每个用户平均有大约50个交易。这意味着,你可能并不是真的 有太多用户,交易超过100,所以数量 更新(希望)不会太多。 =>程序运行得相当快。
  • 使用新列删除应该再次快速。