MySQL-普通索引和唯一索引怎么选择
来自mysql45讲第9讲普通索引和唯一索引应该怎么选择
案例:DBA 的同学跟我反馈说,他负责的某个业务的库内存命中率突然从 99% 降低到了 75%,整个系统处于阻塞状态,更新语句全部堵住。而探究其原因后,我发现这个业务有大量插入数据的操作,而他在前一天把其中的某个普通索引改成了唯一索引。
结论:这两类索引在查询能力上是没差别的,主要考虑的是对更新性能的影响。普通索引性能要高于唯一索引。所以建议你尽量选择普通索引。
-
change buffer的定义:
可以提高数据更新的性能,如果需要更新的数据已经在buffer pool中则直接修改;如果不在buffer pool中则把需要更新的数据先记录在change buffer中,
有后台线程定期进行merge或数据库关闭的时候或访问这个变更的数据时进行merge(合并),防止了要更改的数据不在buffer pool中从磁盘加载到buffer pool中的随机读。
将 change buffer 中的操作应用到原数据页,得到最新结果的过程称为 merge -
change buffer的作用:
change buffer 的主要目的就是将记录的变更动作缓存下来,所以在一个数据页做 merge 之前,change buffer 记录的变更越多,收益就越大,防止了要更改的数据不在buffer pool中从磁盘加载到buffer pool中的随机读。 -
应用场景:
change buffer只适用于普通索引,唯一索引不能使用。
对于唯一索引来说,所有的更新操作都要先判断这个操作是否违反唯一性约束。而这必须要将数据页读入内存才能判断。
如果都已经读入到内存了,那直接更新内存会更快,就没必要使用 change buffer 了。
如果所有的更新后面,都马上伴随着对这个记录的查询,那么你应该关闭 change buffer。而在其他情况下,change buffer 都能提升更新性能。
说明:redo log 主要节省的是随机写磁盘的 IO 消耗(转成顺序写),而 change buffer 主要节省的则是随机读磁盘的 IO 消耗。
相关参数:
change buffer 用的是 buffer pool 里的内存,因此不能无限增大。
change buffer 的大小,可以通过参数 innodb_change_buffer_max_size
来动态设置。
这个参数设置为 50 的时候,表示 change buffer 的大小最多只能占用 buffer pool 的 50%。
innodb_change_buffering
参数用来控制对哪些操作启用 Change Buffer 功能,默认是all。
innodb_change_buffering
参数有以下几种选择:
=all: 默认值。开启buffer inserts、delete-marking operations、purges
=none: 不开启change buffer
=inserts: 只是开启buffer insert操作
=deletes: 只是开delete-marking操作
=changes: 开启buffer insert操作和delete-marking操作
=purges: 对只是在后台执行的物理删除操作开启buffer功能
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?