MySQL聚簇索引和非聚簇索引的区别详情


Posted in MySQL onJune 14, 2022

前言:

在 MySQL 默认引擎 InnoDB 中,索引大致可分为两类:聚簇索引和非聚簇索引,它们的区别也是常见的面试题,所以我们今天就来盘它们。

聚簇索引

聚簇索引(Clustered Index)一般指的是主键索引(如果存在主键索引的话),聚簇索引也被称之为聚集索引。

聚簇索引在 InnoDB 中是使用 B+ 树实现的,比如我们创建一张 student 表,它的构建 SQL 如下:

drop table if exists student;
create table student(
    id int primary key,
    name varchar(16),
    class_id int not null,
    index (class_id)
)engine=InnoDB;
-- 添加测试数据
insert into student(id,name,class_id) values(1,'张三',100),
    (2,'李四',200),(3,'王五',300);

以上 student 表中有一个聚簇索引(也就是主键索引)id,和一个非聚簇索引 class_id。

聚簇索引 id 对应的 B+ 树如下图所示: 

MySQL聚簇索引和非聚簇索引的区别详情

 在聚簇索引的叶子节点直接存储用户信息的内存地址,我们使用内存地址可以直接找到相应的行数据。

非聚簇索引

非聚簇索引在 InnoDB 引擎中,也叫二级索引,以上面 student 表为例,

在 student 中非聚簇索引 class_id 对应 B+ 树如下图所示: 

MySQL聚簇索引和非聚簇索引的区别详情

从上图我们可以看出,在非聚簇索引的叶子节点上存储的并不是真正的行数据,而是主键 ID,所以当我们使用非聚簇索引进行查询时,首先会得到一个主键 ID,然后再使用主键 ID 去聚簇索引上找到真正的行数据,我们把这个过程称之为回表查询

总结

在 MySQL 的 InnoDB 引擎中,每个索引都会对应一颗 B+ 树,而聚簇索引和非聚簇索引最大的区别在于叶子节点存储的数据不同,聚簇索引叶子节点存储的是行数据,因此通过聚簇索引可以直接找到真正的行数据;而非聚簇索引叶子节点存储的是主键信息,所以使用非聚簇索引还需要回表查询,因此我们可以得出聚簇索引和非聚簇索引的区别主要有以下几个:

  • 聚簇索引叶子节点存储的是行数据;而非聚簇索引叶子节点存储的是聚簇索引(通常是主键 ID)。
  • 聚簇索引查询效率更高,而非聚簇索引需要进行回表查询,因此性能不如聚簇索引。
  • 聚簇索引一般为主键索引,而主键一个表中只能有一个,因此聚簇索引一个表中也只能有一个,而非聚簇索引则没有数量上的限制。

到此这篇关于MySQL聚簇索引和非聚簇索引的区别详情的文章就介绍到这了,更多相关MySQL聚簇索引和非聚簇索引内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!


Tags in this post...

MySQL 相关文章推荐
MySQL中in和exists区别详解
Jun 03 MySQL
MySQL REVOKE实现删除用户权限
Jun 18 MySQL
MySQL系列之六 用户与授权
Jul 02 MySQL
MySQL中utf8mb4排序规则示例
Aug 02 MySQL
mysql配置SSL证书登录的实现
Sep 04 MySQL
mysql事务对效率的影响分析总结
Oct 24 MySQL
Mysql中一千万条数据怎么快速查询
Dec 06 MySQL
JMeter对MySQL数据库进行压力测试的实现步骤
Jan 22 MySQL
mysql insert 存在即不插入语法说明
Mar 25 MySQL
详解MySQL的主键查询为什么这么快
Apr 03 MySQL
MySQL数据库Innodb 引擎实现mvcc锁
May 06 MySQL
手把手带你彻底卸载MySQL数据库
Jun 14 MySQL
关于mysql中string和number的转换问题
Jun 14 #MySQL
mysql实现将字符串字段转为数字排序或比大小
Jun 14 #MySQL
手把手带你彻底卸载MySQL数据库
MYSQL中文乱码问题的解决方案
Jun 14 #MySQL
MySQL运行报错:“Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre”解决方法
Jun 14 #MySQL
MySql如何将查询的出来的字段进行转换
Jun 14 #MySQL
MySQL安装失败的原因及解决步骤
You might like
PHP 之Section与Cookie使用总结
2012/09/14 PHP
PHP编译安装时常见错误解决办法
2015/05/28 PHP
php多重接口的实现方法
2015/06/20 PHP
PHP入门教程之表单与验证实例详解
2016/09/11 PHP
简单谈谈PHP中的trait
2017/02/25 PHP
PHP中trait使用方法详细介绍
2017/05/21 PHP
laravel config文件配置全局变量的例子
2019/10/13 PHP
php 使用ActiveMQ发送消息,与处理消息操作示例
2020/02/23 PHP
纯js实现的论坛常用的运行代码的效果
2008/07/15 Javascript
利用JS延迟加载百度分享代码,提高网页速度
2013/07/01 Javascript
ajax请求get与post的区别总结
2013/11/04 Javascript
多选列表框动态添加,移动,删除,全选等操作的简单实例
2014/01/13 Javascript
基于iframe实现类似于ajax的页面无刷新
2014/05/31 Javascript
jquery checkbox 勾选的bug问题解决方案与分析
2014/11/13 Javascript
纯javascript代码实现计算器功能(三种方法)
2015/09/07 Javascript
JS实现同一个网页布局滑动门和TAB选项卡实例
2015/09/23 Javascript
javascript比较语义化版本号的实现代码
2016/09/09 Javascript
jQuery 常见小例汇总
2016/12/14 Javascript
对称加密与非对称加密优缺点详解
2017/02/06 Javascript
jQuery实现图片滑动效果
2017/03/08 Javascript
vue2.0+vue-router构建一个简单的列表页的示例代码
2019/02/13 Javascript
VUEX 数据持久化,刷新后重新获取的例子
2019/11/12 Javascript
[02:02:38]VG vs Mineski Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
Python的Flask框架应用调用Redis队列数据的方法
2016/06/06 Python
Python的爬虫框架scrapy用21行代码写一个爬虫
2017/04/24 Python
Pycharm学习教程(6) Pycharm作为Vim编辑器使用
2017/05/03 Python
TensorFlow实现非线性支持向量机的实现方法
2018/04/28 Python
python代码过长的换行方法
2018/07/19 Python
python支付宝支付示例详解
2019/08/22 Python
在Python中获取操作系统的进程信息
2019/08/27 Python
python 错误处理 assert详解
2020/04/20 Python
打印tensorflow恢复模型中所有变量与操作节点方式
2020/05/26 Python
python如何调用php文件中的函数详解
2020/12/29 Python
详解HTML5中rel属性的prefetch预加载功能使用
2016/05/06 HTML / CSS
工业自动化专业毕业生推荐信
2013/11/18 职场文书
cf收人广告词
2014/03/14 职场文书