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

标签 mysql transactions innodb temp-tables

我已经查看了找到的所有相关问题,但找不到一个可以回答我的问题。

我有一张这样的 table :

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

其中“id”是主键,... 表示大约有 30 列。 “active”列是tinyint类型。

我的任务:

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

我做到了:

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

  • 引擎是InnoDB

<小时/>

我的问题:

有人告诉我,执行这样的查询相当于执行 5 个查询,因为 IN 会转换为给定数量的 OR,然后依次运行它们。

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

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

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

<小时/>

你有什么建议?我认为 INSERT INTO .. ON 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.

谢谢。

最佳答案

情况正好相反。 OR 有时可以变成 IN。然后,IN 会被有效执行,尤其是在列上有索引的情况下。如果 IN 中有 1000 个条目,它将根据 id 对表进行 1000 次探测。

如果您正在运行足够新的 MySQL 版本,我认为您可以执行 EXPLAIN EXTENDED UPDATE ...OR...;显示警告; 查看此转换;

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

如果您将 UPDATE 分解为多个 UPDATE,每个 UPDATE 包含 100-1000 行,那么对于系统的其他用户来说可能会更好。 More on chunking .

你首先从哪里获得 id 的?如果它是通过 SELECT 实现的,那么将其与 UPDATE 结合起来使其一步而不是两步可能会更实用。

关于Mysql 在一个查询中更新多行中的一列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41105168/

相关文章:

带词边界的 MySQL 全文搜索

mysql - 从数据库中获取所有订单 - 只返回一行

python - 如何在django中创建新的数据库连接

python - 数据库事务如何与应用程序代码一起工作

mysql - Rails 4 - 从 SQLite 切换到 MySQL - 无法添加外键约束

mysql - CakePHP(子)查询以获取每个组的最年轻记录

mysql - 如何计算 Ruby on Rails 上的文本长度?

c# - NHibernate 中的非锁定事务

mysql - 关于 MySQL 中 InnoDB 死锁的问题?

mysql - InnoDB:启动mamp时无法锁定错误45