✅什么是聚簇索引和非聚簇索引、以及回表、索引下推

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,企业版 4核16GB
推荐场景:
HTAP混合负载
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 数据库中的聚簇索引和非聚簇索引是两种不同的数据组织方式。聚簇索引将数据与索引一起存储,主键决定行的物理顺序,适用于InnoDB。非聚簇索引则索引与数据分开,叶子节点存储主键值和指针。在查询时,非聚簇索引需回表操作找到主键后再查询数据。无主键时,InnoDB会自动生成隐藏主键。覆盖索引和索引下推是优化查询的技术,覆盖索引允许仅通过索引获取数据,减少回表;索引下推可在存储引擎层面部分执行过滤条件,降低回表次数。

聚簇索引(Clustered Index)和非聚簇索引(Non-clustered Index)是数据库中的两种索引类型,它们在组织和存储数据时有不同的方式。

聚簇索引

聚簇索引简单理解就是将数据与索引放在一起,找到索引即找到了数据。换句话说,对于聚簇索引,其非叶子节点上存储的是索引字段的值,而叶子节点上存储的是对应记录的整行数据。

image.png

在 InnoDB 中,聚簇索引(Clustered Index)是指按照每张表的主键构建的一种索引方式。它将表数据按照主键的顺序存储在磁盘上,确保了行的物理存储顺序与主键的逻辑顺序相同。这种索引方式使得查找聚簇索引的速度非常快。

非聚簇索引是指将索引与数据分开存储的一种方式。在非聚簇索引中,叶子节点包含索引字段的值以及指向数据页数据行的逻辑指针。

image.png

在 InnoDB 中,非聚簇索引(Non-clustered Index)是根据非主键字段创建的索引,通常称为二级索引。它不影响表中数据的物理存储顺序,而是单独创建一张索引表,用于存储索引列和对应行的指针。

在 InnoDB 中,主键索引就是聚簇索引,而非主键索引则是非聚簇索引。因此,在 InnoDB 中:

  • 对于聚簇索引,其非叶子节点上存储的是索引值,而叶子节点上存储的是整行记录。
  • 对于非聚簇索引,其非叶子节点上存储的是索引值,而叶子节点上存储的是主键的值以及索引值。

因此,通过非聚簇索引进行查询时,需要进行一次回表操作,即先通过索引查找到主键 ID,然后再通过 ID 查询所需字段。

没有创建主键怎么办?

在 InnoDB 中,如果表结构中没有定义主键,数据库会自动为每行记录添加一个隐藏的主键,通常称为 db_row_id 字段。这个隐藏主键会确保每行记录都有一个唯一的标识符。

如果表中没有合适的唯一索引可用作聚簇索引,数据库会使用这个隐藏主键来构建聚簇索引。这样可以确保每行记录都有一个物理上的唯一标识符,并且能够保持索引的唯一性和快速查询的特性。

扩展知识

我们刚刚又提到回表的概念,什么是回表呢?

什么是回表,怎么减少回表的次数?

在 InnoDB 中,索引 B+树的叶子节点存储了整行数据的是主键索引,也被称为聚簇索引。而索引 B+树的叶子节点存储了主键的值的是非主键索引,也被称为非聚簇索引。

在数据存储方面,主键(聚簇)索引的 B+树的叶子节点直接包含了我们要查询的整行数据。而非主键(非聚簇)索引的叶子节点则包含了主键的值。

因此,当我们通过非聚簇索引进行查询时,首先会通过非聚簇索引查找到主键的值,然后需要再通过主键的值进行一次查询才能获取到我们要查询的数据。这个过程称为回表。

因此,在 InnoDB 中,使用主键进行查询效率更高,因为这个过程不需要回表。此外,通过依赖覆盖索引、索引下推等技术,我们可以通过优化索引结构和 SQL 语句来减少回表的次数。

什么是索引覆盖、索引下推?

覆盖索引

覆盖索引是指查询语句的执行只需从索引中获取所需数据,而无需从数据表中读取。也可以称之为实现了索引覆盖。

当一条查询语句符合覆盖索引条件时,MySQL 只需通过索引就能返回查询所需数据,而不需要进行索引查找后再返回表操作,从而减少 I/O,提高效率。

例如,在表 covering_index_sample 中有一个普通索引 idx_key1_key2(key1,key2)。

当我们执行以下 SQL 语句时:

SELECT key2 FROM covering_index_sample WHERE key1 = 'keytest';

此时可以通过覆盖索引查询,无需进行回表操作。

但是对于以下 SQL 语句,虽然是索引覆盖,但由于不符合最左前缀匹配,无法利用索引(会扫描索引树):

SELECT key1 FROM covering_index_sample WHERE key2 = 'keytest';

另外,如果查询语句中需要的信息不包含在联合索引中,那么就无法使用索引覆盖。例如:

SELECT key2, key3 FROM covering_index_sample WHERE key1 = 'keytest';

索引下推

索引下推是 MySQL 5.6 引入的一种优化技术,默认开启,可通过设置 SET optimizer_switch = 'index_condition_pushdown=off'; 来关闭。

它的工作原理如下:假设 people 表中(zipcode,lastname,firstname)构成一个索引。考虑以下查询:

SELECT * FROM people WHERE zipcode='95054' AND lastname LIKE '%etrunia%' AND address LIKE '%Main Street%';

如果没有使用索引下推技术,MySQL 会通过 zipcode='95054'从存储引擎中查询对应的数据,然后将结果返回到 MySQL 服务端,接着 MySQL 服务端再基于lastname LIKE '%etrunia%' 和 address LIKE '%Main Street%'来判断数据是否符合条件。

而如果使用了索引下推技术,MySQL 首先会返回符合 zipcode='95054'的索引,然后根据lastname LIKE '%etrunia%'来判断索引是否符合条件。如果符合条件,则根据该索引定位对应的数据;如果不符合,则直接拒绝。有了索引下推优化,可以在有 like 条件查询的情况下,减少回表次数。

当一条 SQL 使用到索引下推时,执行计划中的 extra 字段的内容会显示为 "Using index condition"

索引下推不止 like

上面的例子中,提到了 like,包括 MySQL 官网中也只提到了 like,但是其实不止有 Like。因为我认为索引下推其实是解决索引失效带来的效率低的问题的一种手段

所以当联合索引中,某个非前导列因为索引失效而要进行扫表并回表时,就可以进行索引下推优化了。

如,有 a,b 联合索引,类型都是 varchar,以下 SQL 也可以用到索引下推:

select d from t2 where a = "ni" and b = 1;

因为 b 字段因为类型不匹配导致索引失效了,但是通过下推优化其实是可以减少回表的次数的。

好了,本章节到此告一段落。希望对你有所帮助,祝学习顺利。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
SQL 关系型数据库 MySQL
mysql索引(七)唯一索引
唯一索引(UNIQUE):与"普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值。
378 0
mysql索引(七)唯一索引
|
27天前
|
存储 关系型数据库 数据库
【随手记】聚簇索引、二级索引和联合索引
【随手记】聚簇索引、二级索引和联合索引
25 2
|
2月前
|
存储 关系型数据库 索引
MyISAM主键索引树和二级索引树
MyISAM主键索引树和二级索引树
40 0
MyISAM主键索引树和二级索引树
|
2月前
|
存储 关系型数据库 数据库
|
12月前
|
存储 关系型数据库 MySQL
什么是MySQL索引下推
MySQL索引下推(Index Condition Pushdown)是一种优化技术,它将查询条件下推到存储引擎层进行过滤,减少了存储引擎返回给MySQL服务器的数据量,从而提高查询性能。
126 0
|
12月前
|
存储 数据库 索引
聚簇索引和非聚簇索引
聚簇索引和非聚簇索引
70 0
|
存储 数据库 索引
聚簇索引与非聚簇索引
聚簇索引和非聚簇索引是关系数据库中常用的两种索引类型。它们在数据存储和索引组织方式上存在一些区别。下面将详细介绍聚簇索引和非聚簇索引的定义、特点以及适用场景。
205 0
|
存储 数据库 索引
聚簇索引什么是非聚簇
聚簇索引和非聚簇索引是数据库中常见的两种索引类型,它们在索引数据的组织方式和存储结构上有所不同。下面我将详细介绍聚簇索引和非聚簇索引的概念、特点和使用场景。
52 0
|
存储 Oracle 关系型数据库
主键索引是聚集索引还是非聚集索引
在聚簇索引中,主键索引的叶子节点存储的就是数据行本身,因此主键索引也被称为聚簇索引。在这种情况下,主键索引的物理顺序与数据行的物理顺序是一致的,这样可以提高查询性能和范围查询的效率。
92 0
|
存储 SQL 算法
聚簇索引和非聚簇索引区别
聚簇索引和非聚簇索引区别
134 0