MySQL索引介绍

索引的定义

  • 扇区:磁盘存储的最小单位,扇区一般大小为512Byte。
  • 磁盘块:文件系统与磁盘交互的的最小单位(计算机系统读写磁盘的最小单位),一个磁盘块由连续几个(2^n)扇区组成,块一般大小一般为4KB。
  • MySQL页 : MySQL和磁盘交互的最小单位,相当于4个磁盘块,16KB
  • 顺序IO:按物理存储顺序连续读取/写入数据,预读机制有效,减少磁头寻道时间(对HDD特别重要)。
  • 随机IO:随机IO是跳跃式读写,访问不连续的数据块,HDD 磁头需要频繁移动,难以有效利用预读,SSD 表现更好但仍有性能损耗。

总结:数据库最大的性能损耗就在磁盘IO上,这也是Redis比MySQL快很多的最大原因。索引是依靠某些数据结构和算法来组织数据,尽最大可能去利用磁盘的的顺序IO,并减少IO的次数来优化数据库的访问速度。

MySQL的索引结构

通过索引的定义接下来看MySQL索引数据结构,是如何实现顺序IO,和减少IO访问次数。
MySQL的索引采用B+tree的数据结构,是一种平衡多路查找树(不是二叉,是多叉),最下层的称之为叶子节点,叶子节点的上层为非叶子节点。叶节点具有相同的深度,节点的数据 key 从左到右递增。

非叶子节:

  • 一个非叶子节点只存储多个索引键值和对应的指针,不存储实际数据记录,这些节点在磁盘上以页(Page,16KB)为单位进行存储。这样可以有效降低B+tree的层数,降低IO次数。
  • 一次IO读取可以读取更多的索引键值,大幅降低降低IO读取次数。(MySQL以页为单位和磁盘进行交互)

叶子节点:

  • 在聚簇索引中:存储完整的行数据(包含索引键值)
  • 在二级索引中:存储索引列的值 + 主键值
  • 双向链表结构,支持范围查找,可以沿着叶子节点的链表顺序遍历,避免从根节点查找,减少IO次数

索引的分类

  • 聚集索引 :每个表有且一定会有一个聚集索引,关键字为主键,没有指定主键则自动添加一个隐藏的rowid(4byte)作为主键,所以也叫主键索引
  • 非聚集索引(辅助索引):叶子节点存储索引字段和主键值,其他子节点只存储索引字段
  • 回表 因索引叶子节点只存储主键和索引字段,如果查询其他字段就需要再查询一次主键索引,这就是回表。

索引的缺点

  • 增加存储成本
    索引本身需要占用一定的存储空间。对于大型数据库表,索引文件可能会变得非常庞大。例如,一个包含大量文本字段的数据库表,若在多个列上建立索引,索引文件的大小可能会与数据表本身的大小相当,甚至超过数据表的大小。这就需要额外的磁盘空间来存储索引数据,增加了存储成本。
  • 降低写入性能
    在对数据表进行插入(INSERT)、更新(UPDATE)和删除(DELETE)操作时,数据库需要同时维护索引的正确性。这些额外的操作会增加写入操作的时间和资源消耗,从而降低写入性能。特别是在高并发的写入场景下,频繁地维护索引可能会导致性能瓶颈。

索引使用原则

  • 最左原则: 复合索引 (a,b,c ) 如果查询条件只有 c = ? 或 b = ? and c= ? 时不会走索引,只有使用最左边的a 为条件时才会走索引。
  • 前缀匹配:使用like时,% 在前会使索引失效,%在后时,只能使用部分索引。
  • 索引区分度:索引区分度 = count(distint 记录) / count(记录),索引区分度非常小就接近于全表扫描了,所以创建索引时要选择区分度高的。
  • in 查询 相当于多个 唯一记录检索,然后合并结果。
  • 当多个条件中有索引的时候,并且关系是and的时候,会走索引区分度高的。
  • 避免回表操作,在设计数据库时,需要根据业务场景评估是否需要创建聚簇索引或合适的二级索引,以减少回表操作。
  • 字符串索引列,查询条件为 和 int比较 会导致索引失效。
  • int 索引列,查询条件为 和字符串比较,索引不会失效。
  • 使用union 关键字代替 or 。
  • 索引字段,使用函数,索引无效。
  • 索引字段使用运算符,索引无效 id +1 = 2 无效 id= 2+1索引有效。
  • 使用索引优化排序,B+树 就是按照索引值排序的链表,查询的结果自带排序。
相关推荐
草莓熊Lotso1 小时前
【Redis 初阶】Set 类型深度解析:去重集合的运算能力与实战场景
linux·网络·数据库·windows·redis·tcp/ip·缓存
煎饼皮皮侠3 小时前
【设计】设计一个web版的数据库管理平台后端(之五) --借鉴mybatis
数据库·mybatis
东风破_9 小时前
danci 2:创建的单词书到底存在哪里?从 Supabase 一路理解 ORM、Drizzle 和 RLS
数据库·后端·node.js
九皇叔叔10 小时前
《MySQL 体系架构详解:Server 层、SQL 执行流程与 InnoDB、MyISAM、MEMORY 存储引擎》
sql·mysql·架构
橙子家10 小时前
OSS 文件上传的几个风险点和解决方案
数据库
2601_9620664912 小时前
【Sql Server】Update中的From语句,以及常见更新操作方式
android·java·数据库
愤怒的苹果ext13 小时前
MySQL Shell备份恢复数据库
数据库·mysql·备份恢复·mysqlsh
数字新视界15 小时前
DCIM管理系统的技术架构与部署模式详解
数据库·物联网·数据中心·数据中心基础设施管理·dcim管理系统
何以解忧,唯有..15 小时前
Pydantic 介绍与使用:Python 数据校验的现代方案
数据库·python·microsoft
超兔一体云16 小时前
MySQL索引优化实战——从慢查询到索引调优
后端·mysql