如何在mysql中更新多个记录

时间:2014-05-05 08:31:11

标签: mysql sql sql-update scheduler mysql-event

我想计算mysql中数百万条记录的兴趣。所以我使用的是调度程序

create event cal_interest 
on every 1 day 
do 
update 
userTable
set interest=(money*rate)/100 

我的问题是:
1。是否有可能同时更新数百万条记录?
2。任何记录更新的可能性和一些失败。
3。如果计算多个记录的利息是错误的,那么请建议我怎么做?

1 个答案:

答案 0 :(得分:3)

  1. 一般来说,一次更新数百万行并不是一个好主意。特别是如果你有数据库集群(几乎肯定会有复制延迟)。更好的策略是将更新分成几批。

  2. 是。总是存在失败的可能性

  3. 参见1 :)将您的表拆分为N批记录(N从100到1000),并逐批更新。其中一个策略是创建一个启动和监视这些批量更新的客户端作业。 (一种可能的方法:添加一个索引字段来存储上次更新的日期,然后选择N行,其中包含last_update_date< current_date)

  4. 评论:通过"拆分表"我并不意味着身体分裂,只是以下几点:

    • 添加保存上次同步日期的字段(并将其编入索引)(例如last_sync_date);

    • 当作业开始时,在循环内执行以下操作:

      • 使用last_sync_date<

      • 检索下N个记录的ID(例如N = 500)。 CURDATE():

      • 如果你没有得到任何东西,你就完成了,退出了周期;

      • 否则,set interest=(money*rate)/100, last_sync_date = curdate()表示具有这些ID的记录。

      我宁愿这样做是作为一个在MySQL之外编写的工作,并通过例如cron (因为这样可以更容易地监控作业如何运行并在必要时杀死它),但理论上你可以在MySQL中执行它,例如(未经测试)类似的东西(我假设您的记录具有存储在字段id)中的唯一ID:

    delimiter |
    
    create event cal_interest 
    on every 1 day 
    do
        create temporary table if not exists temp_ids(id int) engine=memory;
        declare keep_sync int default 1;
        begin
            repeat
                truncate temp_ids;
                insert into temp_ids(id) select id from userTable where last_sync_date < curdate() limit 500;
                select count(1) from temp_ids into keep_sync;
                update userTable set interest=(money*rate)/100, last_sync_date = curdate() where id in (select id from temp_ids) ids;
            until keep_sync>0;
            drop table temp_ids;
        end |
    
    delimiter ;