MySQL聚簇索引、非聚簇索引、覆盖索引详解

 更新时间:2024年12月25日 09:27:25   作者:高锰酸钾_  
这篇文章详细介绍了聚簇索引、非聚簇索引和覆盖索引的概念,并通过图示和实例说明了索引查找的过程和回表查询的概念,同时,文章也提到了覆盖索引的优点和弊端,并给出了适用场景

聚簇索引、非聚簇索引、覆盖索引

本篇将带你搞懂什么是聚簇索引、非聚簇索引、覆盖索引,并且通过画图的方式了解索引查找的过程,明白什么是回表查询

索引(Index)是数据库中一种用于快速查找和访问表中数据的结构,它类似于书的目录,通过索引可以快速定位到目标数据,而无需遍历整个表,索引的存在可以显著提高查询速度,尤其是在处理大量数据时

MySQL中默认使用索引的数据结构是B+树,详细可以参考:MySQL索引为什么是B+数

那什么又是聚簇索引、非聚簇索引、覆盖索引?

聚簇索引

聚簇索引也叫聚集索引,是一种将数据行的物理存储顺序与索引的逻辑顺序相同的索引,换句话说,数据是直接存储在索引的叶子节点中,通过主键查找到某一行数据,这一行数据的全部内容都存放在这个叶子节点中,聚簇索引必须有,而且只能有一个。

以下面这个表为例:

idnameusernameage
1001张三zhangsan20
1002李四lisi18
1003王九wangjiu35
1004赵六zhaoliu22
1005王八wangba17
1006李白libai40
1007杜甫dufu33

以主键id来为其生成一个简单的B+树索引为:

这个利用主键字段来生成的索引就是一个聚簇索引,当我们通过id查找某一个用户时,通过查找算法,找到了他所在的叶子节点,那么在这个叶子节点中,就存放了该用户的整行数据,包括姓名、账号、年龄:

如果定义了主键,MySQL会自动将主键列作为聚簇索引;如果没有主键,MySQL会选择一个唯一非空索引;如果没有唯一索引,MySQL会生成一个隐藏的rowid作为主键来生成聚簇索引

非聚簇索引

相比于聚簇索引,非聚簇索引也叫二级索引,它的叶子节点存储的是索引列的值以及指向实际数据行的指针(或主键值),而不是完整的数据行,也就是说,非聚簇索引的叶子节点中,存放的不再是整行数据,而是该行数据的主键

当我们为上表建立索引时,使用的不是id,而是username

默认会使用字母顺序来进行排序,但是其叶子节点中存储的不再是整行数据,而是该行数据的索引值

回表查询

回表查询是数据库查询中的一个术语,指的是在使用非聚簇索引(或普通索引)时,数据库查询引擎需要通过索引查找到对应的行号(或主键值),然后再回到表中查找完整的行数据的过程

以上表为例,我们想要查询usernamezhaoliu的用户全部信息:

select * from user where username = 'zhaoliu'

1.此时回先到username的非聚簇索引中去查找

通过username的比对查找,找到了zhaoliu所在的叶子节点,但是叶子节点中并没有我们需要的全部用户信息,只有该用户的主键值id

2.这时就会拿着id去聚簇索引中比对查找

找到该用户的叶子节点,再把叶子节点中的整行数据返回

回表查询增加了 I/O 操作,尤其是表数据量大时会显著降低性能,所以我们在设计索引时,尽量要避免出现回表查询

当查询的字段较少且频率较高时,建议使用覆盖索引优化查询

覆盖索引

覆盖索引(Covering Index) 是一种索引优化技术,指的是查询所需的所有字段都可以直接从索引中获取,无需再回表查询。这种方式可以显著提高查询性能,因为避免了回表操作

也就是说,当我们建立索引时,不再使用单一字段来建立索引,而是包含多个字段,这样在利用索引进行查询信息时,叶子节点中可以包含全部的所需数据,不必再到其他索引中查询,因此可以避免回表查询

比如之前以username建立的索引,如果我们不查询用户的全部数据,而是只需要返回usernameid

select id,name from user where name = 'zhangsan'

username建立的索引中已经包含了想要的全部数据:usernameid,因此不需要再去查询其他的索引,这就是覆盖索引

在建立索引时,可以设置多字段建立索引:

CREATE INDEX idx_name_age ON users(name, age)

这样索引的叶子节点中就存放了更多的数据

当我们查询所需要的信息nameage时,索引 idx_name_age 包含 nameage,因此查询所需的字段完全覆盖,无需回表

SELECT name, age FROM users WHERE name = 'John'

但是覆盖索引也有一些弊端:

  • 1.增加存储开销
  • 索引存储需要额外空间,字段越多,索引越大。
  • 2.写性能受影响
  • 插入、更新、删除操作需要同时更新覆盖索引,导致写入开销增加。
  • 3.适用场景有限
  • 覆盖索引适用于查询固定字段的场景,但无法应对动态字段需求。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 简单的MySQL备份与还原方法分享

    简单的MySQL备份与还原方法分享

    这篇文章主要介绍了简单的MySQL备份与还原方法,文中Linux与Windows的两种情况都有介绍,需要的朋友可以参考下
    2015-08-08
  • 如何用word vb宏来生成sql

    如何用word vb宏来生成sql

    本篇文章是对利用word vb宏来生成sql的方法进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • DBA应该知道的一些关于SQL Server跟踪标记的使用

    DBA应该知道的一些关于SQL Server跟踪标记的使用

    本篇文章小编为大家介绍,DBA应该知道的一些关于SQL Server跟踪标记的使用。需要的朋友参考下
    2013-04-04
  • 利用Sqoop实现MySQL数据导入Hive的全流程

    利用Sqoop实现MySQL数据导入Hive的全流程

    在大数据领域中,MySQL 和 Hive 是两种常见的存储工具,MySQL 适合事务处理,而 Hive 则是用于离线数据分析的利器,本文将全面讲解如何使用 Sqoop 将 MySQL 数据导入 Hive 的完整流程,包括环境配置、具体操作步骤以及最佳实践和常见问题解决方案,需要的朋友可以参考下
    2024-12-12
  • MySQL中修改lower_case_table_names方式

    MySQL中修改lower_case_table_names方式

    这篇文章主要介绍了MySQL中修改lower_case_table_names方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • Mysql 5.7.18 利用MySQL proxies_priv实现类似用户组管理

    Mysql 5.7.18 利用MySQL proxies_priv实现类似用户组管理

    这篇文章主要为大家详细介绍了Mysql 5.7.18利用MySQL proxies_priv实现类似用户组管理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • linux Xtrabackup安装及使用方法

    linux Xtrabackup安装及使用方法

    Xtrabackup是一个对InnoDB做数据备份的工具,支持在线热备份(备份时不影响数据读写),是商业备份工具InnoDB Hotbackup的一个很好的替代品
    2013-04-04
  • Mysql的复合索引如何生效

    Mysql的复合索引如何生效

    本文主要介绍了Mysql的复合索引如何生效,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • MYSQL删除表中的指定ID数据

    MYSQL删除表中的指定ID数据

    有些时候我们需要删除表中指定ID数据,主要是接下模糊删除,需要的朋友可以参考下
    2013-01-01
  • sql ROW_NUMBER()与OVER()方法案例详解

    sql ROW_NUMBER()与OVER()方法案例详解

    这篇文章主要介绍了sql ROW_NUMBER()与OVER()方法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08

最新评论