普通索引和唯一索引,傻傻分不清楚?

两种索引对查询语句和更新语句的性能影响来进行分析

查询过程

假设,执行查询的语句是 select id from T where k=5。这个查询语句在索引树上查找的过 程,先是通过 B+ 树从树根开始,按层搜索到叶子节点,也就是图中右下角的这个数据页,然后 可以认为数据页内部通过二分法来定位记录。 对于普通索引来说,查找到满足条件的第一个记录 (5,500) 后,需要查找下一个记录,直到 碰到第一个不满足 k=5 条件的记录。 对于唯一索引来说,由于索引定义了唯一性,查找到第一个满足条件的记录后,就会停止继 续检索。

那么,这个不同带来的性能差距会有多少呢?答案是,微乎其微。

更新过程

在说之前,先引入一个新的东东,change buffer。何为change buffer???

当需要更新一个数据页时,如果数据页在内存中就直接更新,而如果这个数据页还没有在内存中 的话,在不影响数据一致性的前提下,InooDB 会将这些更新操作缓存在 change buffer 中, 这样就不需要从磁盘中读入这个数据页了。在下次查询需要访问这个数据页的时候,将数据页读 入内存,然后执行 change buffer 中与这个页有关的操作。通过这种方式就能保证这个数据逻 辑的正确性。

它存在的意义就是能够减少对硬盘IO的操作,我先保存着更新操作,等你要查,我才拿到缓存中更新,再给你呈现。懂了吗?

回到更新操作。。。

对于唯一索引来说,所有的更新操作都要先判断这个操作是否违反唯一性约束。比如,要插入 (4,400) 这个记录,就要先判断现在表中是否已经存在 k=4 的记录,而这必须要将数据页读入内 存才能判断。如果都已经读入到内存了,那直接更新内存会更快,就没必要使用 change buffer 了。 因此,唯一索引的更新就不能使用 change buffer,实际上也只有普通索引可以使用。

你看接下来这俩种情况你就会恍然大悟

第一种情况是,这个记录要更新的目标页在内存中。这时,InnoDB 的处理流程如下:

  • 对于唯一索引来说,找到 3 和 5 之间的位置,判断到没有冲突,插入这个值,语句执行结 束;
  • 对于普通索引来说,找到 3 和 5 之间的位置,插入这个值,语句执行结束。

这样看来,普通索引和唯一索引对更新语句性能影响的差别,只是一个判断,只会耗费微小的 CPU 时间。

但,这不是我们关注的重点。

第二种情况是,这个记录要更新的目标页不在内存中。这时,InnoDB 的处理流程如下:

  • 对于唯一索引来说,需要将数据页读入内存,判断到没有冲突,插入这个值,语句执行结 束;
  • 对于普通索引来说,则是将更新记录在 change buffer,语句执行就结束了。

 

由于唯一索引用不上 change buffer 的优化机制,因此如果业务可以接受,从性能角度出发我 建议你优先考虑非唯一索引。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值