Mysql 的锁与索引的关系

                                  mysql 锁与索引的关系

  mysql的锁:(行锁,表锁,页锁) 与索引存在很大的关系,我们平时在写sql的时候其实很少注意这个问题(估计是个人水平比较低,所以很少注意吧),那么在有索引和没有索引的时候数据库锁的策略是什么呢?

首先我们知道如果没有建立索引的话我们在进行数据选取或者定位的时候是通过全表扫描的形式来进行的,比如存在这样一张表user(id,name,phone,address);并且这张表中并没有任何索引,那么sql:delete from user where name='张三' 这样一个语句是如何定义到张三这个记录的,因为没有索引,所以在数据库实现的时候是对整张表进行扫描的,那么数据库是不是会把整张表锁定起来呢?我们测试一下:

我们先看看数据库表user的定义和数据,可以看到我们没有定义任何索引,当然primarykey这默认是一个索引,但是这并不能影响我们的操作。

A. 首先我们查看一下我们的数据库表表结构和数据:


可以发现我们在这个表中出了主键(默认的唯一索引),并没有额外定义索引。

A.我们先测试一下,使用主键对数据库表进行操作会不会导致全表锁定。(因为mysql默认是autocommit=1,所以我们应该手动控制事务)


从上面我们可以看到左边进程开启了一个事务,并且对id=1的数据进行修改,但是此刻并没有进行提交,那么我们肯定是获取到了这一行的锁,在另外一个进行中我们同样对数据进行修改,发现数据修改成功了,那么可以证明:通过索引进行数据库锁定的时候并不会封锁表的其他记录。那么如果不是会封锁这条记录呢?


这样,我们同时没有释放左边进程得到的锁,同时我们更改被锁定的行:发现超时了,这是因为在innodb中(myisam中并不支持行锁)提供了主动判断死锁的方法,我们通过设置innodb_lock_wait_timeout来决定发生死锁多长时间会主动回滚一个事务。这里可以发现在where出使用主键(默认的索引) 确实会导致表中被操作的这行数据被锁定。

    如果我们更改的时候不使用索引,那么数据库锁定的粒度到底是多大呢?

A处开启事务,并更改了一行数据,但是并没有使用索引,在这个时候是需要对表进行全盘扫描的,那么我们在右边进程中再次对表中另一个记录进行修改,结果:再次timeout。这里我们可以得出一个结论: 不使用索引的数据库操作获取到的锁会导致整个表的锁定。


温习一下就得知识: 看上图中AB 两处:为什么左边提交事务右边再一次查看就能够看到事务呢?这是因为mysql默认的事务隔离级别为repeatable reader。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值