Mysql在一个查询中更新一行多行

时间:2016-12-12 16:24:03

标签: mysql transactions innodb temp-tables

我已查看过我发现的所有相关问题,但无法找到能回答我的问题。

我有一张这样的桌子:

id | name | age | active | ...... | ... |

其中" id"是主键,而...意味着有30列。 "活跃" column是tinyint类型。

我的任务:

在单个查询中更新ID 1,4,12,55,111(这些只是一个示例,它可以是1000个不同的id),active = 1。

我做了:

UPDATE table SET active = 1 WHERE id IN (1,4,12,55,111)
  • 在交易中,因为我在此过程中更新了其他内容。

  • 引擎是InnoDB

我的问题:

有人告诉我,执行此类查询相当于执行时的5个查询,因为IN将转换为给定数量的OR,并逐个运行它们。

最终,而不是1我得到N,这是IN中的数字。

他建议创建一个临时表,在其中插入所有新值,然后通过join更新。

他说得对吗?两者的等效性和性能。

你有什么建议?我认为INSERT INTO ..在DUPLICATE UPDATE会有所帮助,但我没有该行的所有数据,只有它是id,并且我想设置active = 1。

也许这个查询更好?

UPDATE table SET
active = CASE
WHEN id='1' THEN '1'
WHEN id='4' THEN '1'
WHEN id='12' THEN '1'
WHEN id='55' THEN '1'
WHEN id='111' THEN '1'
ELSE active END
WHERE campaign_id > 0;  //otherwise it throws an error about updating without where clause in safe mode, and i don't know if i could toggle safe mode off.

感谢。

2 个答案:

答案 0 :(得分:1)

反过来说。 OR有时可以变为IN。然后有效地执行IN,尤其是在列上有索引的情况下。如果IN中有1000个条目,它将根据id对表格进行1000次探测。

如果您运行的是足够新版本的MySQL,我认为您可以EXPLAIN EXTENDED UPDATE ...OR...; SHOW WARNINGS;查看此转换;

UPDATE CASE...可能会繁琐地检查每一行。

如果您将UPDATE分成多个UPDATEs,每个有100-1000行,那么系统的其他用户可能会更好。 More on chunking

你从哪里获得了ids?如果它是通过SELECT,那么将它与UPDATE结合使用可能是一步而不是两步。

答案 1 :(得分:0)

我认为下面更好,因为它使用主键。

UPDATE table SET active = 1 WHERE id<=5