如何在mysql中快速更新数百万行

时间:2016-09-19 09:49:15

标签: mysql

我需要在数据库中更新超过400万行。我们目前正在使用mysql 5.1,而且更新速度非常慢。目前,不到10万行的时间超过30分钟,这是不可取的。

我有一个sql脚本,它自动生成我需要的更新语句并将它们输出到文件中。我已经尝试将其分解为多个文件,看看这是否加快了速度,但无济于事。

我的脚本使用select concat生成update语句并将它们写入文件,如下所示:

 SELECT CONCAT("UPDATE status SET next_status_id=", ts_next.id, ",duration=",
 SUM(UNIX_TIMESTAMP(ts_next.status_date) - UNIX_TIMESTAMP(ts.status_date)),
  " WHERE id =", ts.id, " AND next_status_id IS NULL AND duration = 0;")
 into outfile '/tmp/status_updates.sql'
 FIELDS TERMINATED BY '' 
 LINES TERMINATED BY '\n'
FROM
   status ts
        LEFT JOIN
      status ts_next ON ts_next.ticket_id = ts.ticket_id
        AND ts_next.id = (SELECT 
            MIN(id)
        FROM
            status first_status
        WHERE
            first_status.id > ts.id AND first_status.ticket_id = ts.ticket_id)
            GROUP BY ts.id;

理想情况下,我希望尽快完成这些更新,并且对所有建议持开放态度,以最小的方式实现此目标。

解决方案:

UPDATE status ts1,
    (SELECT 
    ts_next.id as next_status_id,
    ts.id as status_id,
    IFNULL(SUM(UNIX_TIMESTAMP(ts_next.status_date) - UNIX_TIMESTAMP(ts.status_date)), 0) as duration
    FROM
   status ts
        LEFT JOIN
      status ts_next ON ts_next.ticket_id = ts.ticket_id
        AND ts_next.id = (SELECT 
            MIN(id)
        FROM
           status first_status
        WHERE
            first_status.id > ts.id AND first_status.ticket_id = ts.ticket_id)
            GROUP BY ts.id) ts2
    SET ts1.next_status_id = ts2.next_status_id, ts1.duration = ts2.duration 
    WHERE id=ts2.status_id AND ts1.next_status_id IS NULL;

1 个答案:

答案 0 :(得分:1)

使用“更新 - 选择”。我认为它应该是更新许多行的最快方法。因此,请看这个问题: MySQL - UPDATE query based on SELECT Query