mysql中update使用in并在in中使用子查询出现的效率问题

系统上线后,后台一接口超时,定位是MySQL中Update语句里使用In并含子查询导致性能问题。如特定Update语句,单独部分或转为Select无问题,但此写法结合一定数据量易出性能问题。解决办法一是将In中查询在后端先执行再传参,二是套一层子查询提前执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    在昨天系统上线之后发现后台有一个接口一直是超时状态,翻来覆去看了很多的地方同时也想了很多原因最后在定位在一条更新语句出现了性能问题导致的接口超时.

    这种sql就是标题说的mysql中update里边使用in并且在in中使用子查询时出现的,具体原因网上有很多的解释,这里就大概说一下

sql的形状是 UPDATE 表X SET  A = 1, B = 2 WHERE C IN (SELECT C FROM 表Y WHERE D = 3) AND E = 5

大家可以看到上边的语句单独哪一部分都不会出现问题,把update转换成select语句也不会出现问题,唯独上边这样写加上表中数据量有一些就有可能出现性能问题.

 

    这块不再啰嗦,具体的解决办法可以将in中的查询单独拉出来在后端先执行然后以参数形式传入即可避免,

    另外一种方法可以尝试改成如下形状只需要套一层  UPDATE 表X SET  A = 1, B = 2 WHERE C IN (

SELECT * FROM (SELECT C FROM 表Y WHERE D = 3) ALLINFO) AND E = 5

   标蓝处再添加一层可将里边的查询提前执行,避免N*N次这样的慢查询.

### 使用带有子查询UPDATE 语句 在 MySQL 中,`UPDATE` 语句可以结合 `JOIN` 或者嵌套子查询来实现复杂的数据更新逻辑。然而需要注意的是,在同一个表内执行先读取再更新的操作时存在限制[^1]。 #### 更新单个字段的情况 当目标是从另一张表获取值用于更新当前表的一个或多个字段时,可以通过如下方式: ```sql UPDATE table_name AS t1 SET column_to_update = ( SELECT value_column FROM another_table WHERE some_condition AND t1.id = another_table.ref_id ) WHERE EXISTS (SELECT * FROM another_table WHERE some_condition AND t1.id = another_table.ref_id); ``` 此方法适用于简单的基于单一条件匹配场景下的跨表更新操作[^3]。 #### 复杂条件下多字段更新 对于更复杂的业务需求,比如需要依据关联关系同时修改多个字段,则推荐采用 `JOIN` 的形式来进行批量更新: ```sql UPDATE table_a a INNER JOIN table_b b ON a.common_field = b.matching_field SET a.column_1 = b.source_value, a.column_2 = CASE WHEN condition THEN expression ELSE default END; ``` 这种方式不仅提高了效率而且增强了可维护性和清晰度[^2]。 #### 解决分页更新的问题 针对某些特殊的需求如需按批次处理大量记录时,虽然直接使用 `LIMIT` 可能会导致语法错误[^4],但可通过引入辅助变量或其他技巧绕过这一限制: ```sql SET @row_number := 0; UPDATE mytable m JOIN ( SELECT id, (@row_number:=@row_number + 1) as row_num FROM mytable ORDER BY sort_key ASC LIMIT 100 OFFSET 500 ) subq ON m.id = subq.id SET m.status = 'processed'; ``` 上述例子展示了如何利用用户定义变量配合子查询完成带偏移量的结果集更新任务。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值