凡事都在事上磨,这样才能精进,成长进步提高! ------ 博客园首页

update未走索引导致全表锁住

事件经过:
前段时间, 自动化测试的小姐姐向我们开发人员反应, 由于我方经常debug导致锁表, 她们的用例经常失败.
该问题出现的时机基本一致,通过show OPEN TABLES where In_use > 0;以及show processlist, 确定sql.
但是奇怪的是这次的事故竟然是把整个表锁了, 而不是以往只是某条数据被锁住(开发和测试未单独分库, 调试时的某些数据偶尔会导致锁表情况).
对sql进行分析后发现, 这条update后面的where竟然没有走索引!!!

原因:
我们使用mysql时一般使用的都是默认引擎innoDB.
而innoDB的行锁是通过给索引上的索引项枷锁来实现的, 而不是针对记录来加锁的.
假如在操作数据的时候, 没有索引, 是无法使用行级锁的, 此时使用的是表锁. (小伙伴们这下明白对mysql来说索引多重要了吧)

引申
同时引申一个有趣的现象. 假如多个线程操作的是不同数据, 也用了索引, 但是为什么还是锁表了呢?
原因还是上面这个, 行锁是在索引上的. 假如你where条件后面分别是: code=“001” and name=“xx” 和code=“001” and name=“yy”, 索引在code上, 那么还是会出现锁表的.
例如:
tdb_goods 表中brand_name上有索引, 而goods_price字段无索引

在线程A中执行
START TRANSACTION;
UPDATE tdb_goods SET is_show=1 WHERE brand_name='苹果' AND goods_price='3388.000';
然后在A执行COMMIT;之前在另一个线程B中开启一个事务并执行UPDATE tdb_goods SET is_show=1 WHERE brand_name='苹果' AND goods_price='2288.000';
此时线程Bmysql会提示:
错误代码: 1205
Lock wait timeout exceeded; try restarting transaction
1
2
3
4
5
6
7
那么
另外需要注意一点: 如果表比较小, 即使有索引, mysql也不一定会走索引而是查全表.
————————————————
版权声明:本文为CSDN博主「yytoo2」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yytoo2/article/details/107557246

posted @   追风fc  阅读(1319)  评论(0编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
历史上的今天:
2019-06-03 思维模式
2019-06-03 kafka的搭建,命令
点击右上角即可分享
微信分享提示