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+树 就是按照索引值排序的链表,查询的结果自带排序。
相关推荐
TDengine (老段)1 小时前
TDengine 语言连接器(Go)
大数据·数据库·物联网·golang·时序数据库·tdengine·iotdb
加油,旭杏1 小时前
【Redis】数据结构和内部编码
数据库·redis·缓存
极限实验室1 小时前
Easysearch 自动备份:快照生命周期管理
数据库
怒放的生命.2 小时前
《MySQL从入门到精通》
android·数据库·mysql
你们补药再卷啦2 小时前
newbee商城购物车模块mapper.xml
java·数据库·sql
在下_诸葛3 小时前
狂神SQL学习笔记一:初识MySQL、关系型数据库和非关系型数据库
数据库·sql·学习
leegong231113 小时前
oracle大师认证证书有用吗
数据库·oracle
略知java的景初3 小时前
MYSQL MVCC详解
mysql
JAVA学习通3 小时前
MySQL联合查询||多表查询
java·数据库·mysql
小趴菜吖3 小时前
数据库的种类及常见类型
数据库