mysql批量更新时遇到的坑

新上线与中台对接的项目,需要批量更新用户表,设置初始状态。
刚开始使用的sql如下:
update car1_user_info set syncplate_state=3 where identity_no in (select pui.certificate_card from platform_user_info pui);
(背景:car1_user_info中有30多万的数据,每天都会有人操作,并且此次整改又添加了,增加中台使用密码的字段,若为空,则登录时会去写入这个表。)

在开发和测试执行这个sql的时候,大概几分钟就执行完了,没有出问题。
在生产环境执行时,执行了几分钟以后,就不动了,查看后台日志发现锁表了。
在plsql中执行
//查看所有进程
show processlist;

//查询是否锁表
show OPEN TABLES where In_use > 0;

//查看被锁住的
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
//等待锁定
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
kill 12041

将锁住的进程删掉即可。

锁表的原因是因为,我使用in来update这张主表,导致这个范围内的用户都被锁定了。另一个用户来进行登录修改用户信息时,就会失败。

(具体关于索引相关的知识待补充)

最后,只能够使用存储过程,先查询出所有需要修改的用户id,然后进行循环id,一条条的更新,因此可以使用存储过程来更新。

DROP PROCEDURE
IF EXISTS userData;

CREATE PROCEDURE userData ()
BEGIN

DECLARE userId LONG;


DECLARE str VARCHAR (300);

#这个用于处理游标到达最后一行的情况  
DECLARE x INT;


DECLARE s INT DEFAULT 0;


DECLARE cursor_name CURSOR FOR 
SELECT
	id_
FROM
	car1_user_info
WHERE
	account IN (
		SELECT
			certificate_card
		FROM
			platform_user_info
	)
and enable_=1
and is_identity=1;


DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'
SET s = 1;


OPEN cursor_name;


WHILE s <> 1 DO
	FETCH cursor_name INTO userId;


UPDATE car1_user_info
SET syncplate_state = 3,remark_="设置同步状态为3"
WHERE
	id_ = userId;
-- 要添加commit,不然还是会锁表
commit;

END
WHILE;

CLOSE cursor_name;


END;

CALL userData ()
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值