How to update millions of rows quickly in mysql
我需要在我的数据库中更新超过400万行。 我们目前正在使用mysql 5.1,而且更新速度非常慢。 目前,不到100,000行的时间超过30分钟,这是不可取的。
我有一个sql脚本,它自动生成我需要的更新语句并将它们输出到一个文件。 我已经尝试将其分解为多个文件,看看这是否加快了速度,但无济于事。
我的脚本使用select concat生成更新语句并将它们写入文件,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 ' ' 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; |
理想情况下,我希望尽快完成这些更新,并且对所有建议持开放态度,以最小的方式实现这一目标。
解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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; |
使用"更新 - 选择"。 我认为它应该是更新许多行的最快方法。 因此,请看这个问题:
MySQL - 基于SELECT Query的UPDATE查询