Mysql优化——唯一索引和普通索引的选择

问题:当一个字段同时满足唯一索引和普通索引的情况下,我们要如何抉择呢?
要弄清楚这个问题,我们首先要了解唯一索引和普通索引的实现原理,我们通过查询操作更新操作分别来对比他们之间的区别

附带一提,普通索引和唯一索引的区别:首先,他们都是索引,然后从字面上来看,普通,就是可重复的索引,唯一索引,就是不可重复的索引。因此他们俩的区别就是一个key可以重复,一个不可重复。

 

查询操作

普通索引:查找到满足条件的第一个记录后,需要查找下一个记录,直到碰到第一个不满足条件的记录。
唯一索引:由于索引定义了唯一性,查找到第一个满足条件的记录后,就会停止继续检索。
因此,普通索引相对于唯一索引要多一些操作。但是,他们之间对于性能的差距却是微乎其微,想知道为什么的朋友可以自己去查询一下相关资料。

 

更新操作

为了说明普通索引和唯一索引对更新语句性能的影响这个问题,我需要先跟你介绍一下 change buffer
当需要更新一个数据页时,如果数据页在内存中就直接更新,而如果这个数据页还没有在内存中的话,在不影响数据一致性的前提下,
InooDB 会将这些更新操作缓存在 change buffer 中,这样就不需要从磁盘中读入这个数据页了。
在下次查询需要访问这个数据页的时候,将数据页读入内存,然后执行 change buffer 中与这个页有关的操作。
通过这种方式就能保证这个数据逻辑的正确性。需要说明的是,虽然名字叫作 change buffer,实际上它是可以持久化的数据。也就是说,
change buffer 在内存中有拷贝,也会被写入到磁盘上。
将 change buffer 中的操作应用到原数据页,得到最新结果的过程称为 merge。除了访问这个数据页会触发 merge 外,系统有后台线程会定期 merge。
在数据库正常关闭(shutdown)的过程中,也会执行 merge 操作。
显然,如果能够将更新操作先记录在 change buffer,减少读磁盘,语句的执行速度会得到明显的提升。
而且,数据读入内存是需要占用 buffer pool 的,所以这种方式还能够避免占用内存,提高内存利用率。

了解了change buffer之后,我要跟大家说的是,只有普通索引才能使用change buffer,唯一索引的更新不能使用change buffer。
但是并不是说,有change buffer就会更好,我们根据上面的原理可以了解到,change buffer是在业务下一次做查询的时候,就会触发merge的过程,
这样随机访问 IO 的次数不会减少,反而增加了 change buffer 的维护代价。
因此在更新操作后马上就要查询的业务情景下,你应该关闭 change buffer, 而在其他情况下,change buffer 都能提升更新性能

回到我们文章开头的问题,普通索引和唯一索引应该怎么选择。

其实,这两类索引在查询能力上是没差别的,主要考虑的是对更新性能的影响。
所以,我建议你尽量选择普通索引

博文参考资料:

《Mysql实战45讲》第九讲09 | 普通索引和唯一索引,应该怎么选择?

  唯一索引和普通索引的区别:https://www.jianshu.com/p/dd4fe101cffe

你可能感兴趣的:(数据库)