索引篇(一)
唯一索引和普通索引,如何选型? 部分转载于 https://time.geekbang.org/column/article/70848
对于同一笔类似的查询操作,使用唯一索引和普通索引的性能差距,微乎其微!
而对于同一笔类似的更新操作,首先说一下mysql是如何完成这个数据页更新的。当更新一个数据页时,如果这个数据页还没加载到我们的内存中,在不影响数据一致性的前提下,会把这些更新先缓存在innodb的change buffer中,这样就不用从磁盘中读入这个数据页了,节省了一次磁盘IO,还可以避免过多占用buffer pool。当下次查询需要访问这个数据页的时候,此时才进行一次磁盘IO,将数据页读入内存中,然后执行change buffer中与这个数据页有关的操作,这个操作称之为merge,除了访问这个数据页触发这个merge外,系统还会有对应的后台线程定时地进行merge。在数据库shut down的时候,也会触发这个merge()。
change buffer就相当于 在内存前置了一个缓冲,用于写内存
对于唯一索引,所有的更新操作都要先判断这个操作是否违反唯一性约束。而当这个数据页还没在内存中,就必须要把这个数据页读入内存。而如果数据页已经存在于内存中,那直接更新内存会更快,就没必要用change buffer。因此唯一索引的更新就不能用change buffer。
(将数据从磁盘读入内存设计随机IO的访问,是数据库里面最高的操作之一),change buffer对更新性能的提升是会很明显的!这里体现一种懒加载的思想。
如果存在大量的更新操作,不建议过多的使用唯一索引,应尽量减少唯一索引的使用或者改为普通索引。
change buffer 的适用最佳场景是 业务写多读少的 常见类为 账单类,日志类系统。
普通索引和唯一索引应该怎么选择。其实,这两类索引在查询能力上是没差别的,主要考虑的是对更新性能的影响。所以,我建议你尽量选择普通索引 。
特别地,在使用机械硬盘时,change buffer 这个机制的收效是非常显著的。所以,当你有一个类似“历史数据”的库,并且出于成本考虑用的是机械硬盘时,那你应该特别关注这些表里的索引,尽量使用普通索引,然后把 change buffer 尽量开大,以确保这个“历史数据”表的数据写入速度。
所以,如果要简单地对比这两个机制在提升更新性能上的收益的话,redo log 主要节省的是随机写磁盘的 IO 消耗(转成顺序写),而 change buffer 主要节省的则是随机读磁盘的 IO 消耗。
change buffer丢失会有影响?
change buffer 会写入系统表空间; 并且在事务提交的时候也写入了redolog; 所以如果发生异常重启,会根据redolog去进行change buffer的恢复。 如果不存在,代表事务没提交成功 ,那change buffer丢失也没事。