MySQL:索引有哪些(清晰明了)

一提到索引,可能就会想到B+树索引、Hash索引、聚簇索引、主键索引、唯一索引、联合索引等等,但这些名词并不能混为一谈,他们有重复的部分,是从不同方面给索引取的名字。

**从数据结构上来讲:**B+树索引、Hash索引、Full-text 索引;

**从物理存储上来讲:**聚簇索引(主键索引)、二级索引(辅助索引);

**从索引字段上来讲:**主键索引、唯一索引、普通索引、前缀索引;

**从字段数量上来讲:**单列索引、联合索引;

那么我就从各个方面来介绍一下这些索引:

1、从数据结构上来讲

1.1 B+树索引

InnoDB 是在 MySQL 5.5 之后成为默认的 MySQL 存储引擎,B+Tree 索引类型也是 MySQL 存储引擎采用最多的索引类型。

B+Tree 是一种多叉树,叶子节点才存放数据,非叶子节点只存放索引,而且每个节点里的数据是按主键顺序存放的。每一层父节点的索引值都会出现在下层子节点的索引值中,因此在叶子节点中,包括了所有的索引值信息,并且每一个叶子节点都有两个指针,分别指向下一个叶子节点和上一个叶子节点,形成一个双向链表。

  • 高效的查找、插入和删除操作。
  • 优化的磁盘读写:B+树的结构减少了磁盘I/O操作,因为它将节点大小设置为与磁盘块相等,这减少了磁盘访问次数。
  • 支持范围查询:叶子节点的链表结构使得B+树特别适合执行范围查询,能够快速地遍历指定范围的所有值。

1.2 Hash索引

Memory引擎默认支持哈希索引,如果多个Hash值相同,出现哈希碰撞,那么索引就以链表方式存储。InnoDB或MyISAM存储引擎页支持Hash索引,但是需要通过伪Hash索引来实现,叫自适应Hash索引。

优点:

  • 查询速度非常快,只需一次哈希计算即可定位到相应的键值。
  • 适用于等值查询。

缺点

  • 无法支持范围查询,因为哈希索引不具备排序特性。
  • 无法进行模糊查询(例如 like 'xxx%')。
  • 内存占用较高,因为需要存储哈希值。

1.3 全文索引

Full-text索引一般使用倒排索引实现。倒排索引同B+tree索引一样,也是一种索引结构。

MySQL中InnoDB存储引擎在之前版本中是不支持全文检索的,要使用全文检索的话只能使用MySIAM存储引擎。在 MySQL 5.6.4 版本中InnoDB存储引擎才开始支持Full-text索引。

对于文本类型的大对象,或者较大的CHAR类型的数据,如果使用普通索引,那么匹配文本前几个字符还是可行的,但是想要匹配文本中间的几个单词,那么就要使用LIKE %word%来匹配,这样需要很长的时间来处理,响应时间会大大增加,这种情况,就可使用时FULLTEXT索引了,在生成FULLTEXT索引时,会为文本生成一份单词的清单,在索引时及根据这个单词的清单来索引。

  • 优点
    • 用于全文搜索,支持关键词匹配。
    • 适用于模糊查询和文本内容搜索。
  • 缺点
    • 占用空间较大。
    • 不适合精确匹配

2、从物理存储上来讲

2.1聚簇索引

主键索引的 B+Tree 的叶子节点存放的是实际数据,所有完整的用户记录都存放在主键索引的 B+Tree 的叶子节点里,当通过聚簇索引查询的时候,不需要回表,因为这个索引中存储了这张表中所有数据。

聚簇索引的创建:

  • 如果有主键,默认会使用主键作为聚簇索引的索引键(key);
  • 如果没有主键,就选择第一个不包含 NULL 值的唯一列作为聚簇索引的索引键(key);
  • 在上面两个都没有的情况下,InnoDB 将自动生成一个隐式自增 id 列作为聚簇索引的索引键(key);

2.2 非聚簇索引

非聚集索引的结构和聚集索引基本相同(非叶子结点存储的都是索引指针),区别在于叶子节点存放的不是行数据而是数据主键。因此在使用非聚集索引进行查找时,需要先查找到主键值,然后再到聚集索引中进行查找。这过程叫做回表。适合单行查找和特定值查找操作。可以有多个非聚集索引。

回表查询简单来说就是通过非聚集索引查询数据时,得不到完整的数据内容,需要再次查询主键索引来获得数据内容。

所以如果使用非聚集索引后还需要使用其他字段的(包括在where条件中或者select子句中),则需要通过主键索引回表到聚集索引获取其他字段。如果是非聚集索引可以满足SQL语句的所有字段的,则被称为全覆盖索引,没有回表开销。

避免回表查询问题,创建联合索引,如根据姓名查性别,那就建立一个姓名和性别的联合索引,那么再这个联合索引中进行查询的话,有查询字段性别,此时就不用回表,这种行为成为索引覆盖。索引覆盖就是指索引的叶子节点已经包含了查询的数据,满足查询要求,没必要再回表进行查询。

3、从索引字段上来讲

3.1 主键索引

  • 主键索引是一种特殊的唯一索引,要求索引列的值必须唯一且不可为空。
  • 每个表只能有一个主键索引,通常用于标识唯一性的列,如用户ID或订单号。

3.2 唯一索引

  • 唯一索引要求索引列的值必须唯一,但允许包含空值。
  • 适用于需要唯一性约束的列,如邮箱地址或用户名。

3.3普通索引

  • 普通索引是最基本的索引类型,没有特殊限制。
  • 可以在单列上创建,也可以是组合索引。
  • 适用于经常需要查询的列。

3.4前缀索引

  • 前缀索引是指对字符类型字段的前几个字符建立的索引,而不是在整个字段上建立的索引,前缀索引可以建立在字段类型为 char、 varchar、binary、varbinary 的列上。
  • 使用前缀索引的目的是为了减少索引占用的存储空间,提升查询效率。

4、从字段数量上来讲

4.1 单列索引

  • 单列索引是最基本的索引类型,仅对一个列进行索引。
  • 适用于经常需要查询的单个列。
  • 例如,在用户表中对年龄(age)字段建立单列索引。

4.2联合索引

  • 联合索引由多个列组成,可以同时对多个列进行索引。
  • 适用于组合搜索,效率高于单列索引。
  • 注意选择联合索引的列顺序,最左前缀原则。

最左前缀原则

查询中的过滤条件必须从索引的最左边开始,并且不能跳过中间的列。只有当查询条件与索引的最左前缀完全匹配时,索引才能被充分利用。

比如,如果创建了一个 (a, b, c) 联合索引,如果查询条件是以下这几种,就可以匹配上联合索引:

  • where a=1;
  • where a=1 and b=2 and c=3;
  • where a=1 and b=2;

需要注意的是,因为有查询优化器,所以 a 字段在 where 子句的顺序并不重要。

但是,如果查询条件是以下这几种,因为不符合最左匹配原则,所以就无法匹配上联合索引,联合索引就会失效:

  • where b=2;
  • where c=3;
  • where b=2 and c=3;

上面这些查询条件之所以会失效,是因为(a, b, c) 联合索引,是先按 a 排序,在 a 相同的情况再按 b 排序,在 b 相同的情况再按 c 排序。所以,b 和 c 是全局无序,局部相对有序的,这样在没有遵循最左匹配原则的情况下,是无法利用到索引的。

相关推荐
Wang's Blog1 小时前
Redis: 集群环境搭建,集群状态检查,分析主从日志,查看集群信息
数据库·redis
容器( ु⁎ᴗ_ᴗ⁎)ु.。oO1 小时前
MySQL事务
数据库·mysql
数据龙傲天2 小时前
1688商品API接口:电商数据自动化的新引擎
java·大数据·sql·mysql
engineer-gxd3 小时前
MySQL 表的操作
mysql
cyt涛3 小时前
MyBatis 学习总结
数据库·sql·学习·mysql·mybatis·jdbc·lombok
Rookie也要加油3 小时前
01_SQLite
数据库·sqlite
liuxin334455663 小时前
教育技术革新:SpringBoot在线教育系统开发
数据库·spring boot·后端
看山还是山,看水还是。4 小时前
MySQL 管理
数据库·笔记·mysql·adb
fishmemory7sec4 小时前
Koa2项目实战2(路由管理、项目结构优化)
数据库·mongodb·koa
momo小菜pa4 小时前
【MySQL 09】表的内外连接
数据库·mysql