前段时间公司一个项目由于业务量增大,在一条update
语句处报了Lock wait timeout exceeded; try restarting transaction
错误,看起来是由于执行update
语句造成了锁表,这是由于mysql在对非索引字段进行修改时,会使用表锁,但对于索引字段进行修改时则不会产生表锁,只会产生行级锁.还有,如果在使用复杂的查询语句时,也会产生表锁.
解决方案是对where后面的字段加上索引.
产生这样的具体原因是,mysql的条件筛选由两部分组成,一部分是索引筛选,由数据库引擎完成,还有一个是服务端筛选.而服务端筛选会锁住数据库引擎返回的数据.例如在表A中,有字段a,b,其中a为索引,则update table A set b=1 where a>10;
,这个时候由于筛选都是由数据库引擎返回的,所以这时锁住的数据就仅仅是a大于10的部分.
但如果是update table A set b=1 where a>10 and b>1;
这个时候,锁住的数据也是a大于10的部分,倘若索引是字段(a,b), 则锁住的数据是a>10且b>1的部分.
网友评论