在一个查询中更新多行非常慢

时间:2011-09-27 07:19:22

标签: php mysql sql centos

我正在研究使用单个查询一次更新多行的最佳方法。 目前我有:

UPDATE `profiles` SET `name` = CASE `id` WHEN 1 THEN 'John' WHEN 2 THEN 'Jane' END, `gender` = CASE `id` WHEN 1 THEN 'Male' WHEN 2 THEN 'Female' END WHERE `id`=1 OR `id`=2

但是这需要大约4分钟才能完成(我的真实查询是在一个包含2000万行的数据库中的10个字段),而不是需要大约1秒钟的单个更新查询。

我想弄清楚为什么,实际发生了什么?我认为通过在WHERE子句中指定id可以加快它的速度。

3 个答案:

答案 0 :(得分:0)

你有id的索引吗?如果没有,最好创建一个(警告,这可能需要很长时间,在非高峰时段执行此操作):

CREATE INDEX id_idx ON profiles (id);

顺便说一下,对表中有2000万行的10个字段的查询可能需要很长时间,特别是如果没有索引或缓存是冷的话。

更新:为了测试,因为我很好奇,我试图重现你的情况。为此我编写了一些测试数据。

DDL:https://gist.github.com/b76ab1c1a9d0ea071965
更新查询:https://gist.github.com/a8841731cb9aa5d8aa26
用测试数据填充表的Perl脚本:https://gist.github.com/958de0d848c01090cb9d

但是,正如我在下面的评论中已经提到的,Mysql将阻止您插入重复数据,因为id是您的PRIMARY KEY,但不是唯一的。如果您可以对表架构发表评论和/或发布您的DDL,这将有很大帮助。

祝你好运! 亚历克斯。

答案 1 :(得分:0)

你能为个人资料表发布DDL吗?这将有助于查看您设置了哪种索引(例如 - 我们可以假设id列是主键吗?)。如果你正在使用MySQL,那么只需运行'SHOW CREATE TABLE profiles'来生成DDL。

有几点可能会有所帮助:

1)尝试在WHERE子句中使用BETWEEN而不是OR。例如     更新profiles

SET `name` = 

CASE `id` WHEN 1 THEN 'John' 

WHEN 2 THEN 'Jane' END, 

`gender` = CASE `id` 

WHEN 1 THEN 'Male' WHEN 2 THEN 'Female' END 

WHERE `id` between 1 and 2;

2)尝试在单独的查询中拆分查询,以避免使用CASE语句,例如

update `profiles`

set `name` = 'John',

    `gender` = 'Male'

where `id` = 1;

update `profiles`

set `name` = 'Jane',

    `gender` = 'Female'

where `id` = 2;

我不知道这是否可行,因为我不确定你在什么情况下使用查询!希望有所帮助。

答案 2 :(得分:0)

您可以为所有字段指定所有案例,因此我们有更好的想法。如果您有仅针对id = 1和2进行更新的修复案例,则将查询拆分为2个查询,如:

update `profiles` set `name` = 'John', `gender` = 'Male' where `id` = 1; 
update `profiles` set `name` = 'Jane', `gender` = 'Female' where `id` = 2;