谈谈MySQL的索引

底层数据结构

MySQL底层数据结构是采用B+树,与B树的区别在于:

  1. B+树只有叶子节点存放key和data,其他非叶子节点都只存key;而B树的所有节点都存放key和data
  2. B+树的叶子节点间有一个双向链表指引,叶子节点内有一条单链表指引;而B树的叶子节点是独立的
  3. B+树的范围查找只需要遍历链表;而B树需要中序遍历得到结果

聚簇索引与非聚簇索引

聚簇索引:简单来说就是叶子节点保存了key(主键)和data,其中的data保存了所有的数据信息。这也就是为什么InnoDB中“索引即数据,数据即索引”

优点:
  • 数据访问更快 ,因为聚簇索引将索引和数据保存在同一个B+树中,因此从聚簇索引中获取数据比非聚簇索引更快
  • 聚簇索引对于主键的 排序查找 范围查找 速度非常快
  • 按照聚簇索引排列顺序,查询显示一定范围数据的时候,由于数据都是紧密相连,数据库不用从多个数据块中提取数据,所以 节省了大量的io操作
缺点:
  • 插入速度严重依赖于插入顺序 ,按照主键的顺序插入是最快的方式,否则将会出现页分裂,严重影响性能。因此,对于InnoDB表,我们一般都会定义一个自增的ID列为主键
  • 更新主键的代价很高 ,因为将会导致被更新的行移动。因此,对于InnoDB表,我们一般定义主键为不可更新
  • 二级索引访问需要两次索引查找 ,第一次找到主键值,第二次根据主键值找到行数据

 非聚簇索引:又叫二级索引、辅助索引。这里的key是非主键,这里的data通常保存的都是主键的地址值,因此在查询时需要进行回表操作,再走一遍主键索引。

一个库中,只能有一个聚簇索引,可以有多个非聚簇索引(也可以没有)

MyISAM InnoDB对比

MyISAM 的索引方式都是 非聚簇 的,与 InnoDB 包含 1 个聚簇索引是不同的。小结两种引擎中索引的区 别:
① 在 InnoDB 存储引擎中,我们只需要根据主键值对 聚簇索引 进行一次查找就能找到对应的记录,而在 MyISAM 中却需要进行一次 回表 操作,意味着 MyISAM 中建立的索引相当于全部都是 二级索引
InnoDB 的数据文件本身就是索引文件,而 MyISAM 索引文件和数据文件是 分离的 ,索引文件仅保存数据记录的地址。
InnoDB 的非聚簇索引 data 域存储相应记录 主键的值 ,而 MyISAM 索引记录的是 地址 。换句话说,InnoDB的所有非聚簇索引都引用主键作为 data 域。
MyISAM 的回表操作是十分 快速 的,因为是拿着地址偏移量直接到文件中取数据的,反观 InnoDB 是通过获取主键之后再去聚簇索引里找记录,虽然说也不慢,但还是比不上直接用地址去访问。
InnoDB 要求表 必须有主键 MyISAM 可以没有 )。如果没有显式指定,则 MySQL 系统会自动选择一个可以非空且唯一标识数据记录的列作为主键。如果不存在这种列,则MySQL 自动为 InnoDB 表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整型。

索引类型总结

按照数据结构维度划分:

  • BTree 索引:MySQL 里默认和最常用的索引类型。只有叶子节点存储 value,非叶子节点只有指针和 key。存储引擎 MyISAM 和 InnoDB 实现 BTree 索引都是使用 B+Tree,但二者实现方式不一样(前面已经介绍了)。
  • 哈希索引:类似键值对的形式,一次即可定位。
  • RTree 索引:一般不会使用,仅支持 geometry 数据类型,优势在于范围查找,效率较低,通常使用搜索引擎如 ElasticSearch 代替。
  • 全文索引:对文本的内容进行分词,进行搜索。目前只有 CHARVARCHARTEXT 列上可以创建全文索引。一般不会使用,效率较低,通常使用搜索引擎如 ElasticSearch 代替。

按照底层存储方式角度划分:

  • 聚簇索引(聚集索引):索引结构和数据一起存放的索引,InnoDB 中的主键索引就属于聚簇索引。
  • 非聚簇索引(非聚集索引):索引结构和数据分开存放的索引,二级索引(辅助索引)就属于非聚簇索引。MySQL 的 MyISAM 引擎,不管主键还是非主键,使用的都是非聚簇索引。

按照应用维度划分:

  • 主键索引:加速查询 + 列值唯一(不可以有 NULL)+ 表中只有一个。
  • 普通索引:仅加速查询。
  • 唯一索引:加速查询 + 列值唯一(可以有 NULL)。
  • 覆盖索引:一个索引包含(或者说覆盖)所有需要查询的字段的值。
  • 联合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并。
  • 全文索引:对文本的内容进行分词,进行搜索。目前只有 CHARVARCHARTEXT 列上可以创建全文索引。一般不会使用,效率较低,通常使用搜索引擎如 ElasticSearch 代替。

MySQL 8.x 中实现的索引新特性:

  • 隐藏索引:也称为不可见索引,不会被优化器使用,但是仍然需要维护,通常会软删除和灰度发布的场景中使用。主键不能设置为隐藏(包括显式设置或隐式设置)。
  • 降序索引:之前的版本就支持通过 desc 来指定索引为降序,但实际上创建的仍然是常规的升序索引。直到 MySQL 8.x 版本才开始真正支持降序索引。另外,在 MySQL 8.x 版本中,不再对 GROUP BY 语句进行隐式排序。
  • 函数索引:从 MySQL 8.0.13 版本开始支持在索引中使用函数或者表达式的值,也就是在索引中可以包含函数或者表达式。

其他索引优化请移步索引带来的SQL优化_YuuuZh。的博客-CSDN博客

谢谢诸君!

参考:

MySQL索引详解 | JavaGuide(Java面试 + 学习指南)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

YuuuZh。

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

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

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

打赏作者

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

抵扣说明:

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

余额充值