在我们学习MySQL的过程中,肯定了解了索引的一些基本概念,也了解了唯一索引和普通索引的区别,今天我们就简单讨论一下唯一索引和普通索引的使用场景。

我们在开发业务需求时,建立用户信息表是不可避免的。比如维护一个员工信息系统,每个人都有一个身份证号,并且我们的用户代码也保证了不会写入重复的身份证号。在我们查询员工信息时,我们可以在身份证号(u_card)上建立索引。
但是由于身份证号的字段比较大,我们不建议将身份证号码作为主键,那么我们就有两种选择,要么u_card字段创建唯一索引,要么创建一个普通索引。

那我们就考虑一下,从性能的角度来看,选择唯一索引还是普通索引。

查询语句

在查询的过程中,如果我们查询语句select * from table where id=a

对于普通索引,查找到满足条件的第一个记录id=a的数据,需要在查询下一条记录,直到碰到第一个不满足id=a(也就是id=a+1)的语句
对于唯一索引,由于索引定义了唯一性,直接查询到id=a的语句就停止搜索。
这两者性能的差距是微乎其微的,可以忽略不计。

InnoDB的数据按数据页为单位来读写的,也就是说,当读一条记录,并不是将记录本身从磁盘读出来,而是以页为单位,整体读入内存。然后再查找id=a的记录。如果id=a正好在数据页的最后一个记录,那么就要取下一个记录页,但是这种操作对于现在的CPU来说也是可以忽略不计的。

更新语句

在数据库更新记录时,我们先了解一下change buffer。

在数据库更新数据时,如果数据页在内存中就直接更新,但是如果数据页不在内存中,在不影响数据一致性的前提下,InnoDB会将更新操作缓存到change buffer中,这样就不需要从磁盘读入数据页了,等到下次查询用到这个数据页的时候,将数据页读入内存,然后执行change buffer中与这一页有关的操作。

change buffer也是可以持久化的,在内存中有拷贝,也会被写入磁盘。
由于唯一索引,所有的更新操作都要判断是否违反了唯一性约束,这就必须要将数据页读入内存才能判断,因此也就没有必要去使用change buffer了。

由于数据从磁盘读入内存涉及到随机IO操作,这也是最耗费时间的,因此如果使用change buffer可以减少随机磁盘访问,可以提升性能。

还有一个问题,如果我们在使用change buffer机制,然后突然机器异常,会不会丢失change buffer的数据呢。
答案是不会丢失,虽然我们只是更新了内存,但是在事务提交的过程找那个,我们也把change buffer的操作记录到redo log中,在崩溃恢复的时候也可以将change buffer找回来。