《MySQL学习》普通索引和唯一索引效率比较
一.查询
效率比较
由于加了唯一索引的字段具有唯一性,那么MySQL在匹配到索引值时,就不会往后去判断下一条记录是否满足要求,如果是普通索引,则需要继续往后查一条记录是否匹配。但MySQL每次查询都是以页作为单位的,在 InnoDB 中,每个数据页的大小默认是 16KB。,当数据在同一页上时,往后在查询一条记录的效率差是微乎其微的,除非匹配的数据刚好在这一页的最后一行,那么还需要一次IO去读取下一页的数据。
因此,普通索引和唯一索引在查询效率上基本一致,最坏情况需要多读取一页数据
二.更新
change buffer 介绍
当需要更新一个数据页时,如果数据页在内存中就直接更新,而如果这个数据页还没有在内存中的话,在不影响数据一致性的前提下,InnoDB 会将这些更新操作缓存在 change buffer 中,这样就不需要从磁盘中读入这个数据页了。在下次查询需要访问这个数据页的时候,将数据页读入内存,然后执行 change buffer 中与这个页有关的操作。通过这种方式就能保证这个数据逻辑的正确性
需要说明的是,虽然名字叫作 change buffer,实际上它是可以持久化的数据。也就是说,change buffer 在内存中有拷贝,也会被写入到磁盘上。change buffer可以看成也是一个数据页,需要被持久化到 系统表空间(ibdata1),以及把这个change buffer页的改动记录在redo log里,事后刷进系统表空间(ibdata1)。
将 change buffer 中的操作应用到原数据页,得到最新结果的过程称为 merge。除了访问这个数据页会触发 merge 外,系统有后台线程会定期 merge。在数据库正常关闭(shutdown)的过程中,也会执行 merge 操作。显然,如果能够将更新操作先记录在 change buffer,减少读磁盘,语句的执行速度会得到明显的提升。而且,数据读入内存是需要占用 buffer pool 的,所以这种方式还能够避免占用内存,提高内存利用率。
效率比较
如果更新的是唯一索引,由于需要判断是否破坏了唯一性,必须要先将数据读入内存页才能判断。如果都已经读入到内存了,那直接更新内存会更快,就没必要使用 change buffer 了。因此,唯一索引的更新就不能使用 change buffer,实际上也只有普通索引可以使用。
将数据从磁盘读入内存涉及随机 IO 的访问,是数据库里面成本最高的操作之一。change buffer 因为减少了随机磁盘访问,所以对更新性能的提升是会很明显的。
所有如果开启了change buff ,那么在读少写多的环境下,普通索引要比唯一索引快很多