mysql锁与索引
行锁
当走索引就是使用行锁,当索引失效就会使用表锁
对索引使用一下操作导致索引失效
- 计算,如:+、-、*、/、!=、<>、is null、is not null、or
- 函数,如:sum()、round()等等
- 手动/自动类型转换,如:id = "1",本来是数字,给写成字符串了
行锁(写&读)
预先关闭自动提交事务功能
set autocommit=0;
窗口A执行更新语句,当前事务对其他食物不可见 -- 已提交读
update test_innodb_lock set b='a1' where a=1;
SELECT * from test_innodb_lock;
在窗口A食物提交之前,窗口B看到的还是老数据
SELECT * from test_innodb_lock;
行锁(写&写)
窗口A执行更新,不提交
update test_innodb_lock set b='a2' where a=1;
此时,窗口B也执行更新
update test_innodb_lock set b='a3' where a=1;
由于窗口A没有commit,窗口B的事务就会等待获取锁,直到窗口A事务提交
表锁
索引失效,行锁升级为表锁,整个表都被锁住,其他事务等待
*避免使用or关键字变更数据,select可以考虑使用in查询更多的数据,然后在代码里过滤不需要的数据(代价)
多占用空间以减少时间
间隙锁
当我们采用范围条件查询数据时,InnoDB 会对这个范围内的数据进行加锁。比如有 id 为:1、3、5、7 的 4 条数据,我们查找 1-7 范围的数据(><between)。那么 1-7 都会被加上锁。2、4、6 也在 1-7 的范围中,但是不存在这些数据记录,这些 2、4、6 就被称为间隙。