MySQL的聚簇索引和二级索引

索引按照物理实现方式,索引可以分为 2 种:聚簇(聚集)和非聚簇(非聚集)索引。也可以把非聚集索引称为二级索引或者辅助索引。

一.聚簇索引

聚簇索引 并不是一种单独的索引类型,而是一种数据存储方式 (所有的用户记录都存储在了叶子节点),也就是所谓的索引即数据,数据即索引

特点:

1.使用记录主键值的大小进行记录和页的排序,这包括三个方面的含义:

(1)页内的记录是按照主键的大小顺序排成一个单向链表 。

(2)各个存放用户记录的页也是根据页中用户记录的主键大小顺序排成一个双向链表 。

(3)存放目录项记录的页分为不同的层次,在同一层次中的页也是根据页中目录项记录的主键大小顺序排成一个双向链表 。

2.B+树的 叶子节点 存储的是完整的用户记录。

所谓完整的用户记录,就是指这个记录中存储了所有列的值(包括隐藏列)。

把具有这两种特性的B+树称为聚簇索引,所有完整的用户记录都存放在这个聚簇索引的叶子节点处。这种聚簇索引并不需要我们在MySQL语句中显式的使用INDEX语句去创建,InnoDB存储引擎会自动地创建聚簇索引。

优点:

数据访问更快 ,因为聚簇索引将索引和数据保存在同一个B+树中,因此从聚簇索引中获取数据比非聚簇索引更快

聚簇索引对于主键的 排序查找 和 范围查找 速度非常快

按照聚簇索引排列顺序,查询显示一定范围数据的时候,由于数据都是紧密相连,数据库不用从多个数据块中提取数据,所以 节省了大量的IO操作 。

缺点:

插入速度严重依赖于插入顺序 ,按照主键的顺序插入是最快的方式,否则将会出现页分裂,严重影响性能。因此,对于InnoDB表,一般都会定义一个自增的ID列为主键

更新主键的代价很高 ,因为将会导致被更新的行移动。因此,对于InnoDB表,一般定义主键为不可更新

二级索引访问需要两次索引查找 ,第一次找到主键值,第二次根据主键值找到行数据

限制:

对于MysQL数据库目前只有InnoDB数据引擎支持聚簇索引,而MylSAM并不支持聚簇索引。

由于数据物理存储排序方式只能有一种,所以每个MySQL的表只能有一个聚簇索引。一般情况下就是该表的主键。

如果没有定义主键,InnoDB会选择非空的唯一索引代替。如果没有这样的索引,InnoDB会隐式的定义一个主键来作为聚簇索引。

为了充分利用聚簇索引的银簇的特性,所以InnoDB表的主键列尽量选用有序的顺序id,而不建议用无序的id,比如UUID、MD5、HASH、字符串列作为主键无法保证数据的顺序增长

二.二级索引(非聚簇索引、辅助索引)

用c2列的大小作为数据页、页中记录的排序规则,再建一棵B+树,效果如下图所示:

这个B+树与上边介绍的聚簇索引有几处不同:

使用记录c2列的大小进行记录和页的排序,这包括三个方面的含义:

(1)页内的记录是按照c2列的大小顺序排成一个单向链表

(2)各个存放用户记录的页也是根据页中记录的c2列大小顺序排成一个双向链表

(3)存放目录项记录的页分为不同的层次,在同一层次中的页也是根据页中目录项记录的c2列大小顺序排成一个双向链表

(4)B+树的叶子节点存储的并不是完整的用户记录,而只是c2列+主键这两个列的值

(5)目录项记录中不再是主键+页号的搭配,而变成了c2列+页号的搭配

以查找c2列的值为4的记录为例,查找过程如下:

1.确定 目录项记录页

根据根页面 ,也就是页44,可以快速定位到目录项记录所在的页为页42(因为2<4< 9 )

2.通过目录项记录页确定用户记录真实所在的页

在页42中可以快速定位到实际存储用户记录的页,但是由于c2列并没有唯一性约束,所以c2列值为4的记录可能分布在多个数据页中,又因为2<4<=4,所以确定实际存储用户记录的页在页34和页35中

3.在真实存储用户记录的页中定位到具体的记录:

到页34和页35中定位到具体的记录

4.但是这个B+树的叶子节点中的记录只存储了c2和c1〔也就是主键)两个列,所以必须再根据主键值去聚簇索引中再查找一遍完整的用户记录。

概念:回表

根据这个以c2列大小排序的B+树只能确定要查找记录的主键值,所以如果想根据c2列的值查找到完整的用户记录的话,仍然需要到聚簇索引中再查一遍,这个过程称为回表。也就是根据c2列的值查询一条完整的用户记录需要使用到 2 棵B+树!

相关推荐
镜舟科技13 分钟前
时序数据库、实时数据库与实时数仓:如何为实时数据场景选择最佳解决方案?
数据库·物联网·数据分析·时序数据库·olap·实时数仓·实时数据库
麻雀无能为力1 小时前
CAU数据库class2 SQL语言
数据库·sql·oracle
夜松云1 小时前
Qt框架核心组件完全指南:从按钮交互到定时器实现
数据库·qt·交互·信号与槽·ui组件·容器类·定时器机制
计算机学姐1 小时前
基于SpringBoot的小型民营加油站管理系统
java·vue.js·spring boot·后端·mysql·spring·tomcat
Elastic 中国社区官方博客1 小时前
JavaScript 中使用 Elasticsearch 的正确方式,第一部分
大数据·开发语言·javascript·数据库·elasticsearch·搜索引擎·全文检索
vvilkim2 小时前
深度解析:Redis 性能优化全方位指南
数据库·redis·性能优化
小光学长2 小时前
基于vue框架的东莞市二手相机交易管理系统5yz0u(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库
双层木屋2 小时前
使用GoLang版MySQLDiff对比表结构
mysql·golang
Freedom℡2 小时前
Spark,SparkSQL操作Mysql, 创建数据库和表
数据库·spark
羊羊羊i3 小时前
Redis进阶知识
数据库·redis·缓存