从头开始搞懂 MySQL(06)索引的选择

我们已经了解了唯一索引和普通索引的区别,那么在不同的业务场景下,我们应该选择普通索引还是唯一索引呢?

我们还是使用第 4 篇文章 索引 中的例子来说明,假设字段 card 上的值都不重复

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FiouiPK5-1649492267526)(/Users/sunqingda/Library/Application Support/typora-user-images/image-20220409124131622.png)]

我们从这两种索引对查询语句和更新语句的性能影响来进行分析

1、查询过程

执行的 SQL:

SELECT ID FROM test WHERE card = 122234

这个查询语句在索引树上,先是通过 B+ 树从根节点开始,然后按层搜索到叶子结点,也就是中间这个数据页,然后可以认为数据页内部通过二分法来定位记录

InnoDB 的数据是按照页为单位来读写的,当需要读取一条记录的时候,会以页为单位,将其整体读入内存,每个数据页的大小默认为 16KB

  • 对于普通索引来说,查找到满足条件的第一个记录(122234,50)之后,要查找下一个记录,直到碰到第一个不满足条件 card = 122234 的记录
  • 对于唯一索引来说,索引是唯一的,查到第一个满足条件的记录后就停止检索

因为引擎按页进行读取,当找到 card = 122234 的记录的时候,它所在的数据页就已经在内存里了,对于普通索引来说,要多做的查找并判断下一条记录的操作就只需要一次指针寻找和一次计算,如果这个记录是数据页的最后一个记录,这个操作会复杂一些,读取下一个数据页,这个概率几乎可以忽略不计

2、更新过程

2.1 change buffer

普通索引和唯一索引对更新更新语句的性能有什么影响呢?我们先来看一下 change buffer

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

虽然名字叫做 change buffer,实际上 change buffer 在内存中有拷贝,会持久化到磁盘上

purge

将 change buffer 中的操作应用到原数据页,得到最新结果的过程称之为 purge,除了访问这个数据页会触发 purge 外,系统中有后台线程会定期执行 purge,数据库正常关闭过程中也会执行 purge 操作

2.1.1 change buffer 使用

唯一索引的更新操作,都要先判断操作是否违反唯一性约束,比如要插入一条记录,会先查表中是否已经存在,这样会将数据页先读入内存中判断,已经读入到内存中的话直接更新内存会更快,没有必要使用 change buffer,唯一索引更新不能使用 change buffer

change buffer 使用的是 buffer pool 里面的内存,大小可以通过 innodb_change_buffer_max_size 来设置,value 值表示 change buffer 大小能占用 buffer pool 的百分比

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SiwVPQZd-1649492267528)(/Users/sunqingda/Library/Application Support/typora-user-images/image-20220409155827225.png)]

如果我们要在表中插入一条新的记录(12345, 3),InnoDB 的处理流程如下

如果要更新的目标页在内存中:

  • 对于唯一索引,找到 2 和 4 之间的位置,判断没有冲突就插入这个值,语句执行结束
  • 对于普通索引,找到 2 和 4 之间的位置,插入这个值,语句执行结束

如果要更新的目标页不在内存

  • 对于唯一索引,先将数据页读入内存,判断没有冲突,插入值,语句执行结束
  • 对于普通索引,将记录更新在 change buffer,语句执行结束

将数据从磁盘读入内存会涉及随机 IO 的访问,操作的成本较高,change buffer 减少了随机磁盘访问,所以对更新性能的提升会比较明显

2.1.2 change buffer 使用场景

因为 purge 的时候是真正的数据进行更新的时候,change buffer 的主要目的就是将记录的变更动作缓存下来,所以在一个数据页 purge 之前,change buffer 记录越多,更新次数越多,收益就越大

  • 在对于一个写多读少的业务来说,比如订单流水、日志系统等,页面在写完后马上查询的概率较小,比较适合 change buffer 使用
  • 对于写入后立马查询的业务,即使满足了条件先将更新记录在 change buffer 中,但之后立马查询该数据页,就会触发 purge,会增加 IO 次数,不适合 change buffer 使用

如果

索引选择

  • 普通索引和唯一索引在查询能力上区别不大,主要考虑对更新性能的影响,尽量还是考虑使用普通索引
  • 如果在更新后立马伴随对记录的查询,可以关闭 change buffer,其它情况 change buffer 是可以提交性能的
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
如果你从头开始学习MySQL数据库,以下是一个简单的学习路径建议: 1. 学习基本概念:了解数据库的基本概念,如什么是数据库、表、字段、行、列、主键、外键等。可以参考MySQL官方文档或在线教程。 2. 安装和配置MySQL:根据你的操作系统,选择合适的MySQL版本并进行安装。学习如何配置和启动MySQL服务器。 3. 学习SQL语言:SQL是用于与数据库进行交互的语言,学习SQL语句的基本语法和常用操作,如创建表、插入数据、查询数据、更新数据和删除数据等。 4. 数据库设计与规范化:学习如何进行数据库设计,包括确定表结构、定义主键和外键、选择合适的数据类型等。了解数据库规范化的概念和规则,以提高数据库的性能和数据完整性。 5. 学习MySQL工具和命令行:掌握一些常用的MySQL工具,如MySQL Workbench、phpMyAdmin等,并熟悉使用命令行界面进行数据库操作。 6. 索引和查询优化:学习如何创建索引以提高查询性能,了解索引的类型和使用场景。学习如何优化查询语句,包括使用索引、避免全表扫描、合理使用JOIN等。 7. 数据备份和恢复:学习如何进行数据库备份和恢复操作,包括完全备份、增量备份、恢复到指定时间点等。 8. 安全和权限管理:了解如何设置数据库用户和权限,限制用户的访问权限,保护数据库的安全性。 9. 实践项目:通过实践项目来巩固所学知识,例如创建一个简单的数据库应用或进行数据分析。 在学习过程中,可以结合官方文档、在线教程、书籍和实践项目来深入理解和应用MySQL数据库。同时,多与社区和论坛互动,参与讨论和解决问题,以扩展你的知识和技能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一起来搬砖呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值