MySQL 普通索引和唯一索引该如何选择?

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MySQL 普通索引和唯一索引该如何选择?

MySQL 普通索引和唯一索引该如何选择?



普通索引和唯一索引在查询能力上没啥差别,主要考虑对更新性能的影响,要尽量选择普通索引。接下来分析两种索引在查询语句和更新语句对性能的影响。


查询过程


MySQL InnoDB 是采用 B+ 树实现其索引结构。

640.png



B+ 树的查找过程


如上图所示:现在需要查找 29 这个值。

  1. 将磁盘块1从磁盘加载到内存,发生一次IO ,在内存中使用二分查找方式找到 29在17和35 之间,锁定磁盘块1的P2 指针。
  2. 通过磁盘块1 的 P2 指针地址把磁盘块3 加载到内存,发生第二次IO ,锁定磁盘块3 的 P2 指针
  3. 通过磁盘块3 的P2指针加载磁盘块8到内存,发生第三次 IO.同时根据二分查找找到29 查询结束。


640.png

假设用执行这么一个查询语句:


select id from T where k=5

现在索引树上查找,然后通过 B+ 树从树根开始,按层搜索到叶子节点,然后从数据页内部通过二分查找中定位记录。


640.png


  • 对应普通索引来说,查找到满足条件的第一个记录 (5,500) 之后,需要查找下一个记录,直到找到第一个不满足 k =5 的记录终止检索。
  • 对于唯一索引来说,定义了唯一性,找到了第一个满足条件的记录后,停止检索。InnoDB 是按数据页为单位读写的,以页为单位,读入整个内存,每个数据页默认大小 16 K ,由于内存的查找是很快的,即使普通索引会继续查找下一条k=5 的记录,只需要进行一次指针+一次计算,整个性能也是可以忽略不计的,也就是说普通索引和唯一索引在查询性能上差别不是很大


更新过程


change buffer


change buffer 是一个特殊的数据结构,当二级索引的页面不在缓冲池中,change buffer 会缓存对二级索引的数据操作(update, insert, delete).主要减少磁盘的随机 I/O。


唯一索引不会使用 Change buffer ,如果索引设置了唯一属性,在进行插入或者修改操作时,InnoDB 必须进行唯一性检查,如果不读取索引页到缓冲池,无法校验索引是否唯一,但是可以进行缓冲删除操作。


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


change buffer 实际上是持久化的数据,change buffer 在内存中有拷贝,也会被写入到磁盘上。将 change buffer 中的操作应用到原数据页,得到最新结果过程称为 merge,除了访问页这个数据页会触发 merge 操作,系统后台线程会定期 merge ,在数据库正常关闭过程中,也会执行 merge。


change buffer 配置


  • innodb_change_buffer_max_size% 配置写缓冲的大小,占整个缓冲池的比例,默认值是25%,最大值是50%。


show variables like '%innodb_change_buffer_max_size%';


640.png

  • innodb_change_buffering配置是否缓存辅助索引页的修改,默认为 all,即缓存 insert/delete-mark/purge


show variables like '%innodb_change_buffering%';

640.png


如果能够将更新操作先记录 change buffer ,减少读磁盘,语句的执行速度会得到明显提升,而且数据读入内存了需要 buffer pool ,所以使用这种方式能够避免占用内存,提高内存利用率。普通索引能够使用 change buffer ,但是唯一索引不行,因此 普通索引比唯一索引更新操作快。


change buffer 使用场景


  • 适合的场景
  1. 非唯一索引
  2. 业务写多读少,或者不是写后立即读场景。
  • 不合适场景
  1. 数据库都是唯一索引
  2. 写入一个数据后,会立即读取它。


change buffer 和 redo log 区别


redo log 主要节省的是随机写磁盘的 IO 消耗(转成顺序写),而 change buffer 主要节省的是随机读磁盘的IO消耗

快速回忆一遍 redo log


redo log +WAL 技术


redo Log 是 InnoDB 引擎特有的日志。如果每一次更新操作都需要写进磁盘,然后磁盘要找到那条记录,然后再更新,整个过程 IO 成本很高,查找成本很高。MySQL 采用了什么方式提高更新效率呢?


MySQL 采用 WAL 技术,Write Ahead Loging,关键点是先写日志再写磁盘,具体执行如下:当有一条记录需要更新的时候,InnoDB 引擎会先把记录写到 redo log里,并更新内存,这个时候更新就算完事了。当 InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面,这个更新一般是在空闲的时候做。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
缓存 关系型数据库 MySQL
MySQL索引策略与查询性能调优实战
在实际应用中,需要根据具体的业务需求和查询模式,综合运用索引策略和查询性能调优方法,不断地测试和优化,以提高MySQL数据库的查询性能。
161 66
|
5天前
|
SQL 关系型数据库 MySQL
深入解析MySQL的EXPLAIN:指标详解与索引优化
MySQL 中的 `EXPLAIN` 语句用于分析和优化 SQL 查询,帮助你了解查询优化器的执行计划。本文详细介绍了 `EXPLAIN` 输出的各项指标,如 `id`、`select_type`、`table`、`type`、`key` 等,并提供了如何利用这些指标优化索引结构和 SQL 语句的具体方法。通过实战案例,展示了如何通过创建合适索引和调整查询语句来提升查询性能。
44 9
|
2月前
|
存储 关系型数据库 MySQL
阿里面试:为什么要索引?什么是MySQL索引?底层结构是什么?
尼恩是一位资深架构师,他在自己的读者交流群中分享了关于MySQL索引的重要知识点。索引是帮助MySQL高效获取数据的数据结构,主要作用包括显著提升查询速度、降低磁盘I/O次数、优化排序与分组操作以及提升复杂查询的性能。MySQL支持多种索引类型,如主键索引、唯一索引、普通索引、全文索引和空间数据索引。索引的底层数据结构主要是B+树,它能够有效支持范围查询和顺序遍历,同时保持高效的插入、删除和查找性能。尼恩还强调了索引的优缺点,并提供了多个面试题及其解答,帮助读者在面试中脱颖而出。相关资料可在公众号【技术自由圈】获取。
|
2月前
|
SQL 关系型数据库 MySQL
案例剖析:MySQL唯一索引并发插入导致死锁!
案例剖析:MySQL唯一索引并发插入导致死锁!
184 0
案例剖析:MySQL唯一索引并发插入导致死锁!
|
10天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化以及慢查询优化
通过本文的介绍,希望您能够深入理解MySQL索引优化和慢查询优化的方法,并在实际应用中灵活运用这些技术,提升数据库的整体性能。
50 18
|
2天前
|
存储 Oracle 关系型数据库
索引在手,查询无忧:MySQL索引简介
MySQL 是一款广泛使用的关系型数据库管理系统,在2024年5月的DB-Engines排名中得分1084,仅次于Oracle。本文介绍MySQL索引的工作原理和类型,包括B+Tree、Hash、Full-text索引,以及主键、唯一、普通索引等,帮助开发者优化查询性能。索引类似于图书馆的分类系统,能快速定位数据行,极大提高检索效率。
24 8
|
9天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化以及慢查询优化
通过本文的介绍,希望您能够深入理解MySQL索引优化和慢查询优化的方法,并在实际应用中灵活运用这些技术,提升数据库的整体性能。
17 7
|
8天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化与慢查询优化:原理与实践
通过本文的介绍,希望您能够深入理解MySQL索引优化与慢查询优化的原理和实践方法,并在实际项目中灵活运用这些技术,提升数据库的整体性能。
27 5
|
12天前
|
存储 关系型数据库 MySQL
Mysql索引:深入理解InnoDb聚集索引与MyisAm非聚集索引
通过本文的介绍,希望您能深入理解InnoDB聚集索引与MyISAM非聚集索引的概念、结构和应用场景,从而在实际工作中灵活运用这些知识,优化数据库性能。
65 7
|
27天前
|
关系型数据库 MySQL Java
MySQL索引优化与Java应用实践
【11月更文挑战第25天】在大数据量和高并发的业务场景下,MySQL数据库的索引优化是提升查询性能的关键。本文将深入探讨MySQL索引的多种类型、优化策略及其在Java应用中的实践,通过历史背景、业务场景、底层原理的介绍,并结合Java示例代码,帮助Java架构师更好地理解并应用这些技术。
26 2