面试官:MySQL主键为什么不是连续递增的?

设计MySQL表时,我们一般会设置一个自增主键,从而让主键索引尽可能的保持递增的趋势,这样可以避免页分裂,让MySQL顺序写入,大大提高MySQL的性能。

但是,自增主键只能保持大致递增,无法保证顺序递增。

面试官:MySQL主键为什么不是连续递增的?

当我们创建完一个表后,通过show create table命令,可以看到MySQL定义了AUTO_INCREMENT来指定主键的递增值。

在MySQL5.7之前,这个递增值是直接保存在内存里面的,当服务器重启后,MySQL会读取表里面的最大主键id,然后将最大值+1作为下次递增的值。

在MySQL8.0时,将其优化为了保存在redo log中,从而实现了递增值的持久化。

那都有哪些情况可能导致主键不能连续递增呢?

首先我们要知道的是,MySQL对于主键递增值得使用是一次性的,即每次获取完递增值之后,不管接下来的语句是否能真正执行成功,这个递增值都不会再回收利用了。

1,唯一索引冲突导致的主键不连续

有时为了满足业务的需要,我们有时会对表中的字段设置唯一索引。但是当唯一索引冲突时,会产生什么问题呢?

以上面的user表为例,我们对name设置唯一索引。

我们执行两次以下语句:

INSERT into user values (null,'张三','123456');

不难猜到,第二次的执行结果肯定会报错:

面试官:MySQL主键为什么不是连续递增的?

我们在上面已经提到,MySQL对于递增值的使用是一次性的,那么第二次执行插入时,不管语句成功还是失败,那么这个递增值就会浪费掉。

这时,我们再执行一条正常的不冲突的插入语句,会发现主键id产生了间隔。

面试官:MySQL主键为什么不是连续递增的?

2,事务回滚会造成主键不连续

与唯一索引冲突类似,当我们在一个事务中执行插入语句时,那么必然会向MySQL申请一个递增值作为主键id,如果最后事务没有提交,而是回滚,那么这个递增值自然也就浪费掉了。

3,批量插入会造成主键不连续

为了保证主键id的唯一性,在申请自增id时,MySQL会对申请操作加锁。一般情况下,这个申请动作会很快。

对于一般的批量插入,比如insert into … values(xxx),由于插入的Value个数可以提前计算得出,MySQL会一次性的申请足够数量的id,以保证性能。

但是对于insert into … select 这种语句就有点麻烦了,由于无法确定到底需要申请多个主键id,如果插入一条申请一个的话,假设要插入100万条记录,那就得申请100万次,可想而知性能会有多么差劲。

所以对于这种批量插入的语句,MySQL采用了一种翻倍申请的优化策略:

语句执行时,第一次申请一个自增id,第二次申请2个自增id,第三次申请4个自增id…

即每次申请的数量都比上次多一倍,这样虽然会浪费一些自增id,但是可以保证插入的效率,从性能角度来看,是可以接受的。

自增id为什么不回退复用

大家可能会有点疑问,为什么自增id是一次性使用的?

其实原因也很简单,大家稍微一想就明白了。

假设有两个事务在同时执行,为了保证自增id的唯一性,MySQL会对申请动作加锁,然后两个事务各获得一个自增id。比如事务1申请到了自增id100,事务2申请到了自增id101。

当事务2成功提交,事务1因为某些原因回滚了。

如果我们要回退复用事务1的id,将AUTO_INCREMENT又设置成了100+1,那么下一个事务来申请自增id时,就会拿到101,而这时101已经被事务2用掉了,就会造成主键冲突。

当然我们也可以每次都让MySQL检查一下主键是否冲突,如果冲突就跳过这个id,但是这样一来,本来申请自增id这个很轻的动作就会变得很重,对性能的影响就会很大。

所以,从性能角度考虑,InnoDB只保证了主键id是大致递增的,而不保证是顺序递增的。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人,不代表IT壹频道。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。转载请注明出处:https://www.1pindao.com/jingyan/24561.html

(0)
上一篇 2022年 12月 23日 13:39:19
下一篇 2022年 12月 23日 14:08:19

相关推荐

  • 每个领导者都需要知道的6个解决冲突的步骤

    解决冲突是一个复杂的过程,需要一个战略方法。实施正确的冲突解决步骤可以是一个快乐的员工队伍和一个有毒的员工队伍之间的区别。 你解决冲突的努力对于促进团队的团结、协作和凝聚力至关重要。任何错误的措施都可能对团队不利,最终会损害组织。这就是为什么每个优秀的领导者都必须知道如何处理工作场所的冲突。 本文将讨论一些关键和必要的冲突解决步骤,你可以采取这些步骤来解决工…

    2022年 12月 30日
    823
  • 《天下长河》看懂了康熙怒打高士奇,才明白康熙为何重用于振甲

    论做人做事的高手,《天下长河》中的高士奇排名第一;论迂腐无能、损人不利己的第一人,那自然是于振甲。康熙是个不按常理出牌的人,心机很深。他重重摔打帮助自己的高士奇,重用固执无能的于振甲,这绝不是康熙昏了头。从根本上来说,这是康熙设置的一个惊天大局。 要想搞懂这个局是什么,就必须搞清楚3个问题,分别是:一是康熙最缺少什么,二是康熙最需要什么,三是康熙最不需要什么…

    2022年 12月 17日 生活经验
    1.0K
  • 如何使用python绘制渐变色的柱状堆积图?

    前言 python 版本:3.9.5 (tags/v3.9.5:0a7dcbd, May 3 2021, 17:27:52) 演示环境:jupyter-lab 备注:这里默认大家都已经安装了 python 及其相关的工具包。 导入依赖包 获取文件列表,为后面读取数据做准备 在绘制柱状堆积图之前,我们需要为其准备好用于展示的数据。这里我从准备好了的 pickl…

    2023年 1月 8日
    981
  • 走进良性循环最具性价比的方法是什么?

    冯唐在《万物生长》说过一句话: “人比较贱,似乎只有享不了的福,没有受不了的罪。” 顺风顺水时,总想着好不容易过得不错了,放松犒劳下自己吧,然后想干嘛就干嘛; 不如意时,有些人寻求发泄的出口有些人原地抱头迷茫。打开手机,看到一篇篇让你要自律、要努力的鸡血文章,又心烦意乱地关闭。 随顺其自然之下,现状反而日趋狼狈。 迷茫的底色一层层地加厚,每天依然浑浑噩噩,就…

    2022年 11月 6日
    1.3K
  • 销售人员如何提高成交率和销售业绩?

    如何提高成交率,提升销售业绩,这是很多销售员梦寐以求的目标,可是如何能够做到呢。 很多销售员都是从产品出发,见到客户就说产品是如何如何的好,告诉客户,马上就要下架了,机会难得,不能错过,这样,是很难打动到客户的,真正要打动到客户,需要带入情感因素,带入画面感,满足客户的需求,这样才能快速实现成交。 举个例子,你如何能将一个水晶手链推销给一个女性客户,普通销售…

    2022年 11月 18日
    1.1K
  • Word表格常见的技巧有哪些?这9个Word表格小技巧很实用

    我们在日常工作中,经常用到Word办公,下面这9个常见的Word小技巧,能让你的工作省时又省力,一起来看看吧。 01.文字末尾加下划线 Word文字加下划线很简单,但是在文字末尾的空白处,怎么预留下划线呢?你只要连续输入多个空格,然后选中空格,再添加下划线。 02.如何纵向复制文本 我们一般都是横向选择文本,你有没有想过纵向选择文本呢?先按住【Alt】键,然…

    2022年 11月 10日 生活经验
    1.3K