Php 在一个查询中更新多行性能非常慢
我正在寻找用一个查询一次更新多行的最佳方法。 目前我有:Php 在一个查询中更新多行性能非常慢,php,mysql,sql,centos,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个字段上),而单个更
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,可以加快速度。您有id索引吗?如果没有,最好创建一个(警告,这可能需要很长时间,在非高峰时间执行此操作): 顺便说一句,一个表中有2000万行的10个字段的查询可能需要很长时间,尤其是在没有索引或缓存是冷的情况下 更新:为了测试,因为好奇,我试着重现你的情况。为此,我编写了一些测试数据 DDL:
更新查询:
用测试数据填充表的Perl脚本: 然而,正如我在下面的评论中提到的,Mysql将阻止您插入重复数据,因为id是您的主键,但不是唯一的。如果您可以对表模式进行注释和/或发布DDL,这将非常有帮助 祝你好运!
亚历克斯。你有id索引吗?如果没有,最好创建一个(警告,这可能需要很长时间,在非高峰时间执行此操作): 顺便说一句,一个表中有2000万行的10个字段的查询可能需要很长时间,尤其是在没有索引或缓存是冷的情况下 更新:为了测试,因为好奇,我试着重现你的情况。为此,我编写了一些测试数据 DDL:
更新查询:
用测试数据填充表的Perl脚本: 然而,正如我在下面的评论中提到的,Mysql将阻止您插入重复数据,因为id是您的主键,但不是唯一的。如果您可以对表模式进行注释和/或发布DDL,这将非常有帮助 祝你好运!
Alex。请您发布profiles表的DDL好吗?这将有助于了解您设置了什么类型的索引(例如,我们可以假设id列是这里的主键吗?)。如果您使用的是MySQL,那么只需运行“showcreatetableprofiles”来生成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;
及
我不知道这是否可行,因为我不确定您在什么环境下使用查询!希望对您有所帮助。您可以发布profiles表的DDL吗?这将有助于了解您设置了什么类型的索引(例如,我们可以假设id列是这里的主键吗?)。如果您使用的是MySQL,那么只需运行“showcreatetableprofiles”来生成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;
及
我不知道这是否可行,因为我不确定您在什么环境下使用查询!希望对您有所帮助。请您为所有字段指定所有案例,以便我们有更好的想法。如果只有id=1和2的修复案例需要更新,则将查询拆分为两个查询,如下所示:
update `profiles` set `name` = 'John', `gender` = 'Male' where `id` = 1;
update `profiles` set `name` = 'Jane', `gender` = 'Female' where `id` = 2;
请您为所有字段指定所有案例,以便我们有更好的想法。如果只有id=1和2的修复案例需要更新,则将查询拆分为两个查询,如下所示:
update `profiles` set `name` = 'John', `gender` = 'Male' where `id` = 1;
update `profiles` set `name` = 'Jane', `gender` = 'Female' where `id` = 2;
只是一个快速射击。我将为此准备两个不同的查询。使用
CASE
方法可以强制mysql收集您的所有id,即使您指定了其中'id'=1或'id'=2
。如果您直接使用唯一的id
为每个案例准备查询,您将有最快的方法来完成此操作。通过使用2条语句,您还可以获得更清晰的查询,因为此CASE
方法使查询有点奇怪……;)只是一个快速射击。我将为此准备两个不同的查询。使用CASE
方法可以强制mysql收集您的所有id,即使您指定了其中'id'=1或'id'=2
。如果您直接使用唯一的id
为每个案例准备查询,您将有最快的方法来完成此操作。通过使用2条语句,您还可以获得更清晰的查询,因为此CASE
方法使查询有点奇怪……;)我知道我可以单独运行这些,我所追求的是在一个查询中运行它们的方法。我知道我可以单独运行这些,我所追求的是在一个查询中运行它们的方法。我是否正确地理解id的值为1或2,并且可能出现多次?这并不是创建密钥的有效方法。难道表中没有唯一的id可以作为主键吗?在编写一些测试脚本时,我注意到Mysql(正确地)阻止我在id不唯一的情况下插入数据。请与我们共享DDL表,descripe profiles
也就是说?您确定密钥是主密钥吗?还是仅仅是一把简单的钥匙?因为主键不允许colission。我是否正确地理解id的值为1或2并且可能出现多次?这并不是创建密钥的有效方法。难道表中没有唯一的id可以作为主键吗?在编写一些测试脚本时,我注意到Mysql(正确地)阻止我在id不唯一的情况下插入数据。请与我们共享DDL表,descripe profiles
也就是说?您确定密钥是主密钥吗?还是仅仅是一把简单的钥匙?因为主键不允许使用colission。