从mysql查询操作分析:

普通索引:查到满足条件的第一条记录后,还会继续查找下一条记录,直到出现满足条件的记录出现后停止检索

唯一索引:由于索引定义了唯一性,查找到第一个满足条件的记录后,就会停止继续检索

InnoDB 的数据是按数据页为单位来读写的。也就是说,当需要读一条记录的时候,并不是将这个记录本身从磁盘读出来,而是以页为单位,将其整体读入内存。对于查询来说使用这两种索引差别微乎其微。

数据页大小:默认16kb

从mysql更新操作分析:

普通索引更新的时候会使用到change buffer,对于唯一索引来说,所有的更新操作都要先判断这个操作是否违反唯一性约束。唯一索引更新不能使用change buffer。

change buffer是什么?

当需要更新一个数据页,如果数据页在内存中就直接更新,如果不在内存中,在不影响数据一致性的前提下,InnoDB会将这些更新操作缓存在change buffer中。下次查询需要访问这个数据页的时候,将数据页读入内存,然后执行change buffer中的与这个页有关的操作。保证这个数据逻辑的正确性。

change buffer是可以持久化的数据。change buffer主要节省的是随机读磁盘的IO消耗。

知识点补充:

merge:将change buffer中的操作应用到原数据页上,得到最新结果的过程。

访问数据页会触发purge,系统有后台线程定期merge,在数据库正常关闭的过程中,也会执行merge。merge 的时候是真正进行数据更新,change buffer 的主要目的就是将记录的变更动作缓存下来,所以在一个数据页做 merge 之前,change buffer 记录的变更越多(也就是这个页面上要更新的次数越多),收益就越大

怎样设置change buffer

change buffer用的是buffer pool里的内存,大小通过参数innodb_change_buffer_max_size来动态设置。

change buffer使用场景

写多读少的业务场景,常见的业务模型比如:账单、日志类的系统

反例:比如一个业务场景,更新数据后立马做查询操作,数据库会先将更新先记录在 change buffer,但是马上就会访问这个数据页,从而触发 merge 过程。这样操作change buffer反而起了副作用,随机访问IO的次数不会减少,增加了change buffer的维护代价。

索引选择

分析完查询与更新,得出结论:尽量选择普通索引。