第一时间获取技术干货和业界资讯!面试
前面我推荐了极客时间的 Java 高并发课程,不少人根据这篇文章《!(a)(b)2019 Java 高并发学习路线图和必会的 50 道面试题!》的介绍买了课程,我但愿你们可以认真的看!别把钱浪费了!编程
今天,我来讲另一个面试题。为何推荐 MySQL 的 update 语句中 where 条件要有主键?并发
看到这个问题的朋友,我相信很多人有疑问,我 where 不加主键还不能更新了?框架
不是的,能更新,也能使用。可是我不建议大家这样作。由于咱们大多数人使用 MySQL 都使用的是 innodb 存储引擎,它是支持事务的。若是你的 where 条件不加主键,那么 innodb 的行级锁就可能变成表级锁。若是升级为表级锁,那么并发性就将大打折扣了。高并发
以前也有网友在个人文章里评论说,行锁升级为表锁与事务的隔离级别有关,由于事务的隔离性是靠加锁来实现的,而加锁不当势必会影响并发。学习
不同的锁,支持的并发也是不同的。而最终加什么样的锁,与索引也有莫大的关系,所以,能够说采用什么样的索引决定了支持多少并发。测试
经常使用的索引有三类:主键、惟一索引、普通索引。主键我就再也不细说,自带最高效的索引属性;惟一索引指的是该属性值重复率为 0,通常可做为业务主键,例如订单号;普通索引 与前者不一样的是,属性值的重复率大于 0,不能做为惟一指定条件,例如购买用户的姓名。今天我主要想说的是“普通索引对并发的影响”。人工智能
没有索引的状况,我就不说了,那对并发来讲确定是灾难,死锁估计是常有的事。spa
为何我推荐 update 中 where 条件加入主键呢?3d
由于主键是惟一索引,你用其余惟一索引也能够,可是通常的表,可能只有主键才是惟一的。因此,我建议你更新的时候,记住加上主键就好了。
你只须要记住主键和惟一索引是行锁,其余索引并不必定是行锁,极可能是表锁。这样,死锁的几率就很是的高,并发也就随之降低。
下面咱们经过一个简单的例子来看一下,普通索引的状况。
相关建表语句,索引,和数据以下所示:
而后取消事务自动提交 set autocommit = off;
当咱们表里面建立时间重复率比较高的时候。分别开启两个窗口,两个事务。
为了演示,你能够把数据量加多点,好比 03-01 和 03-02 的数据各 10 万条。
依次执行两个窗口中的 SQL,你会发现,其中一个窗口中的更新失败了。提示:
看似这两个事务不互相干,可是在其中一个事务中更新本身锁定的数据失败后,应该能说明在此时引起了表锁。这是在非主键索引或者说是惟一索引,而且索引数据重复量比较高的状况下,你的更新发生量表锁。并发能力就会大大降低!
大家能够试一下,若是此时使用主键或惟一索引会不会这样。
在咱们的电商系统中,这样的代码并很多。在一些热门商品和秒杀、优惠、打折等活动中常常会发生一些莫名其妙的异常,致使用户体验大打折扣。
上面的测试数据,你把它们所有删除,而后再新增一些数据,这些数据中在 create_time 重复率为 0 的状况下,你会发现两个事务就都能成功了。这说明它们这时用的应该是行级锁,效率更高。
以上,测试说明在更新数据时,尽可能使用主键或惟一索引。可是惟一索引并很多每一个表都有的,而主键必须是每一个表都必须有的。因此,我建议大家在更新数据时,都带上主键!
10T技术资源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,GO等等。在公众号内回复对应关键字或框架名字,便可免费获取!!