线上突然出现Lock wait timeout exceeded; try restarting transaction
然后去看sql语句竟然是一段非常简单的UPDATE 语句 条件为id
刚看到这个问题十分震惊,这么简单sql怎么会出现 数据库响应时间超长的问题!?
首先看两段sql 语句:
UPDATE current_audit_node SET del_flag = 1 WHERE id = 1888839568812167170
UPDATE current_audit_node SET del_flag = 1 WHERE id = '1888839568812167170'
不同处就是底下的多了''
一直没有注意过这个问题
数据库该字段使用的是varchar 类型
但是框架生成的sql 其实是UPDATE current_audit_node SET del_flag = 1 WHERE id = 1888839568812167170
id字段其实是一个 long 的数字类型
对于数据库来说认为其是一个 数字类型,但查询对象 为varchar 字符类型
数据库会进行转换导致 执行时间变长
可以看图!
项目初期,平时可能不明显,但数据量一旦过多。
且资源紧张的情况下,就会特别明显
如果数据库字段为varchar java框架中id使用‘’传入
那么速度就为1s左右
但java框架中id不使用‘’传入
UPDATE current_audit_node SET del_flag = 1 WHERE id = 1888839568812167170
实际数字格式,就会出现几十秒执行时间甚至超时的情况
所以id字段类型最好和框架格式统一
目前大多数框架传入 id时 都不使用 ‘’ 虽然框架内是 string
但对于数据库传的是一串数字,会进行转换
所以数据库直接将 id字段类型设置为 bigint 便实现了两方统一
当然java生成id时必须是 纯数字的
当然这也和 数据库连接数过多,数据过多,资源紧张相关
使用
mysql检测是否存在长连接,导致mysql卡住,锁死_mysql 长连接问题排查-优快云博客
中的sql检测长连接,并且杀掉也能暂时解决该问题