【MySQL数据库】普通索引和唯一索引的区别?

上一节,我们学习了关于索引的基本知识——>数据库必学——关于MySQL索引的基础知识都在这!介绍了索引的一些知识,这次我们继续学习数据库索引,今天主要探讨一下在MySQL中,使用普通索引和唯一索引有什么不一样的地方,帮助大家更深入学习到索引。

普通索引和唯一索引

唯一索引:一种索引,不允许具有索引值相同的行,从而禁止重复的索引或键值。系统在创建该索引时检查是否有重复的键值,并在每次使用 INSERT 或 UPDATE 语句添加数据时进行检查。如果已经存在了该值,就会拒接插入和删除。

那么现在我们来看看在不同的操作下它们带来的性能问题吧!

查询情况

在查询的情况下,还是一个学生表,ID为表的索引,如果我们要查询ID为2020001的同学情况是怎么样的呢?

在这里插入图片描述

  • 使用普通索引查到 2020001 这条数据后还会继续查看下一条记录是否符合条件,查询到不符合,则查询结束
  • 使用唯一索引当查到 2020001 这条数据后由于唯一索引的性质,不会有相同的ID,所以就不会继续查找下去了

看起来唯一索引会比普通索引快,那到底会快多少呢?
答: 微乎其微

是不是有点不可思议呢? 那如果你知道InnoDB 对数据的存储方式,这也许就解释的通了。
InnoDB的数据是按数据页为单位来读写的。也就是说,当需要读一条记录的时候,并不是将这个记录本身从磁盘读出来,而是以页为单位,将其整体读入内存。在InnoDB中,每个数据页的大小默认是16KB

因为引擎是按页读写的,所以说,当找到ID = 2020001 的记录的时候,它所在的数据页就都在内存里了。那么,对于普通索引来说,要多做的那一次“ 查找和判断下一条记录 ”的操作,就只需要进行一次指针寻找和一次计算,当然不排除下一个数据是在下一页当中,那样就会比较麻烦些。
但是事实上,一个数据页可以放近千个key,因此出现这种情况的概率会很低。所以,我们计算平均性能差异时,仍可以认为这个操作成本对于现在的CPU来说可以忽略不计。

更新操作

Change buffer

谈到更新操作,就不得不介绍一个新知识出来了 —— change buffer

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

需要说明的是,虽然名字叫作change buffer,实际上它是可以持久化的数据。change buffer在内存中有拷贝,也会被写入到磁盘上

将change buffer中的操作应用到原数据页,得到最新结果的过程称为merge,触发 merge 的情况有:

  • 除了访问这个数据页会触发merge
  • 系统有后台线程会定期merge
  • 在数据库正常关闭(shutdown)的过程中,也会执行merge操作。

显然,使用change buffer 先记录下更新操作不仅可以提高语句执行速度,减少磁盘访问;能减少读入数据对内存的占用,提高内存利用率

好,认识了change buffer 后接着来探讨上面的问题,关于普通索引和唯一索引的更新过程。

已经知道使用change buffer 能明显的优化更新语句的效率,那么你来想想,使用唯一索引查询数据的时候,会使用到change buffer 吗?
是的,不可以的!

为什么呢? 还是因为唯一索引不允许数据键重复,这就使得每一次的插入修改时,都需要使得数据唯一不能违反这个约束,反映在操作上就是引擎将会加载数据页到内存后判断是否存在该要修改的值。既然已经在修改的时候数据就加载到内存,那也就没有必要使用change buffer 了。
换而言之,只有普通索引可以使用change buffer✅,而唯一索引不可🙅‍♂️。

到这里,你是不是和我一样觉得对于普通索引使用change buffer 很有用呢,那是不是普通索引的所有场景,使用change buffer都可以起到加速作用呢?

我们知道,change buffer 的作用就是可以多进行修改但却少进行读写磁盘,也就是merge 的次数尽量少,尽量在积攒了一定数量的更新步骤后,再统一进行merge。反过来说,如果一个业务每进行一次的更新就要马上进行一次的查询,也就是马上就需要将数据页加载到内存中,那其实使用change buffer 的作用并不大,反而还需要增加维护change buffer 的代价。所以,对于写多读少的业务来说,此时change buffer的使用效果最好。这种业务模型常见的就是账单类、日志类的系统。

好了,今天的内容就是这些啦,相信这下你也能正确的分清楚普通索引和唯一索引啦,文章如果有什么问题也欢迎大家指正,希望自己表达的能对你有所帮助,也欢迎大家点赞关注一起进步!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章