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:数据不会丢失