跳转至

09 普通索引与唯一索引的选择

09 普通索引与唯一索引

差别

前提:MySQL InnoDB引擎。在InnoDB中,每个数据页的大小默认是16KB。

查询过程:

  • 普通索引:查询满足条件的第一个记录,之后查找接下来的记录,直到查找不到对应的满足条件的记录;
  • 唯一索引:查询满足条件的第一条记录,返回,(唯一索引唯一性)。

不过对于这种查询,性能差距是微乎其微的。

更新过程:

在更新操作的时候,存在数据页的概念,存在数据页未命中内存,需要从磁盘写入到内存中操作。

两种情况:更新数据页在内存中和不在内存中。

需要更新的记录的数据页在内存中

  • 唯一索引:查找对应的条件,找到对应的位置,判断有没有冲突,插入更新值,结束;
  • 普通索引:查找对应的条件,找到对应的位置,插入更新值,结束。

需要更新的记录的数据页不在内存中

  • 唯一索引:将需要变更新的数据页写入内存,判断有无冲突,插入更新值,结束;
  • 普通索引:将更新记录记录在 change buffer 中,结束。

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

Change buffer

将数据从磁盘读入内存涉及随机IO的访问,是数据库里面成本最高的操作之一。

在业务中,写多读少的场景使用普通索引的性能优势是非常明显的。但是写完立即读取的话,作用就是相反的。

结论:考虑更新场景比较多的情况下,使用普通索引比较好。

Redo 节省的是随机写对磁盘的 IO 操作;

Change Buffer 节省的是随机读对磁盘的 IO 操作。


Q:change buffer一开始是写内存的,那么如果这个时候机器掉电重启,会不会导致change buffer丢失呢?change buffer丢失可不是小事儿,再从磁盘读入数据可就没有了merge过程,就等于是数据丢失了。会不会出现这种情况呢?

A:数据不会丢失