【Mysql】InnoDB 中的聚簇索引、二级索引、联合索引
接上一篇内容。
一、聚簇索引
其实之前内容中介绍的 B+ 树就是聚簇索引。
这种索引不需要我们显示地使用 INDEX 语句去创建,InnoDB 引擎会自动创建。另外,在 InnoDB 引擎中,聚簇索引就是数据的存储方式。
它有 2 个特点:
特点 1
使用记录主键值的大小进行记录和页的排序。
其中又包含了下面 3 个点:
页(包括叶节点和内节点)内的记录按照主键的大小顺序排成一个单向链表。页内记录划分为若干组,每个组中主键值最大的记录在页内的偏移量被当做槽依次存放在页目录中。我们可以通过二分法快速定位主键值等于某个值的记录。
各存放用户记录的页也是根据页中用户记录的主键大小顺序排成一个双向链表。
各存放目录项记录的页分为不同层级。在同一层级中的页,也是根据页中目录项记录的主键大小顺序排成一个双向链表。
特点 2
B+树的叶子节点存储的是完整的用户记录。
这里完整的用户记录就是指,这个记录中存储了所有的列的值(包括隐藏列)。
二、二级索引
聚簇索引只能在我们搜索主键值时才能发挥作用,因为 B+ 树中的数据都是按照主键进行排序。
如果现在我用“别的列”作为搜索条件,怎么办?
答案:再建一个 B+ 树,用这个“别的列”(非主键列)的值大小作为排序规则。
比如之前的内容都是以 c1 列为主键,现在用 c2 列再来创建一个 B+ 树:

看起来跟之前的聚簇索引没啥区别啊?实际上还是存在不同的:
- 使用记录 c2 列的大小进行记录和页的排序。细分的 3 点与上面聚簇索引介绍的一样,只不过上面是主键,这里是用的 c2 列(非主键)。
- B+ 树的叶子节点存储的不是完整的用户记录,只有
c2 列 + 主键这2个列的值。 - 目录项记录中不再是
主键 + 页号,变成了c2 列 + 页号。
另外需要注意的是,因为 c2 列不是主键,所以没有唯一性约束,可能存在多条满足搜索条件的数据。
现在根据条件 c2 = 4 来查找数据记录,过程如下:
- 确定第一条符合 c2 = 4 的目录项所在页,也就是页 42。
- 到页 42 中,进一步确定第一条符合条件的记录所在的用户记录页。因为 2 < 4 <= 4,所以可能存在 页 34 或 35 中。
- 先到页 34 中定位第一条满足 c2 = 4 的用户记录,如果有就不需要再到页 35 中继续定位了。
- 在页 34 中定位到第一条记录。因为这条用户记录不完整,所以拿到这条记录的主键,再到聚簇索引中找到完整的用户记录。
上面最后一步,通过携带主键信息到聚簇索引中重新定位完整的用户记录的过程也叫回表。
回表后,再回到这颗新的 B+ 树,找到刚才那个第一个符合条件的记录,并沿着记录的单向链表向后继续搜索其他也满足 c2 = 4 的记录,每找到一条就继续回表操作,重复这个过程。
这种以非主键列的大小为排序规则而建立 B+ 树需要执行回表操作才可以定位到完整的用户记录,这种 B+树就称为二级索引或者辅助索引。
为什么要回表?直接把完整用户记录都放叶子节点不就可以了?
没错,思路没问题。但是这样操作就相当于每建立一颗 B+ 树都把所有的用户记录复制一遍,太浪费存储空间。
三、联合索引
我们可以同时为多个列建立索引,比如 c2 列和 c3 列,以这 2 个列的大小为排序规则建立的 B+ 树索引就称为联合索引,也称为符合索引或多列索引。
这里的按照 c2 和 c3 列大小进行排序,需要注意两点:
- 先把各个记录和页按照 c2 列进行排序。
- 在记录的 c2 列都相同的情况下,再采用 c3 列进行排序。
现在,给c2 和 c3 建立联合索引,如图所示:

需要注意的是:
- 每条目录项记录都是由 c2、c3、页号这 3 部分组成。各记录先按照 c2 列的值进行排序,如果记录的 c2 列相同,则按照 c3 列进行排序。
- B+ 树叶子节点的用户记录由 c2、c3、和 主键c1 列组成。
本质上,联合索引也是一个二级索引,只不过它的索引列包括 c2、c3 这2个列。
本文参考书籍:
小孩子4919 《mysql是怎样运行的》
【Mysql】InnoDB 中的聚簇索引、二级索引、联合索引的更多相关文章
- MySql InnoDB中的锁研究
# MySql InnoDB中的锁研究 ## 1.InnoDB中有哪些锁### 1. 共享和排他(独占)锁(Shared and Exclusive Locks) InnoDB实现标准的行级锁定,其中 ...
- MySQL单列索引和组合索引(联合索引)的区别详解
发现index merge局限性,优化器会自动判断是否使用 index merge 优化技术,查询还是需要组合索引[推荐阅读:对mysql使用索引的误解] MySQL单列索引和组合索引(联合索引)的区 ...
- 关于mysql索引---联合索引
结论: mysql联合索引,联合索引以哪个字段开始很重要. 如果 联合索引字段为 1,2,3,4 那么如果查询条件为 6,7,8,1 这样也会走上面的联合索引 但是如果查询条件不是从1开始那么则 ...
- MySQL InnoDB中的事务隔离级别和锁的关系
前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力. ...
- MySQL -- Innodb中的change buffer
change buffer是一种特殊的数据结构,当要修改的辅助索引页不在buffer pool中时,用来cache对辅助索引页的修改.对辅助索引页的操作可能是insert.update和delete操 ...
- MySQL/InnoDB中,对于锁的认识
MySQL/InnoDB的加锁,一直是一个面试中常问的话题.例如,数据库如果有高并发请求,如何保证数据完整性?产生死锁问题如何排查并解决?我在工作过程中,也会经常用到,乐观锁,排它锁,等.于是今天就对 ...
- (MYSQL)回表查询原理,利用联合索引实现索引覆盖
一.什么是回表查询? 这先要从InnoDB的索引实现说起,InnoDB有两大类索引: 聚集索引(clustered index) 普通索引(secondary index) InnoDB聚集索引和普通 ...
- MySQL/InnoDB中,乐观锁、悲观锁、共享锁、排它锁、行锁、表锁、死锁概念的理解
文章出处:https://www.souyunku.com/2018/07/30/mysql/?utm_source=tuicool&utm_medium=referral MySQL/Inn ...
- MySQL innodb中各种SQL语句加锁分析
概要 Locking read( SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE),UPDATE以及DELETE语句通常会在他扫描的索引所 ...
随机推荐
- 如何为应用选择最佳的FPGA(上)
如何为应用选择最佳的FPGA(上) How To Select The Best FPGA For Your Application 在项目规划阶段,为任何一个项目选择一个FPGA部件是最关键的决策之 ...
- Spring Cloud系列(六):配置中心
在使用Spring Boot的时候,我们往往会在application.properties配置文件中写一些值,供应用使用,这样做的好处是可以在代码中引用这些值,当这些值需要作出修改的时候,可以直接修 ...
- 【题解】Luogu p3478 [POI2008]STA-Station 动态规划
题目描述 给出一个$N$个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大 输入输出格式 输入格式 第一行一个数$n$,表示树上共有$n$个点接下来$n-1$行,表示$n-1$条边;每行 ...
- K8s 部署 Prometheus + Grafana
一.简介 1. Prometheus 一款开源的监控&报警&时间序列数据库的组合,起始是由 SoundCloud 公司开发的 基本原理是通过 HTTP 协议周期性抓取被监控组件的状态, ...
- 如何在国产龙芯架构平台上运行c/c++、java、nodejs等编程语言
高能预警:本文内容过于硬核,涉及编译器原理.cpu指令集.机器码.编程语言原理.跨平台原理等计算机专业基础知识,建议具有c.c++.java.nodejs等多种编程语言开发能力,且实战经验丰富的资深开 ...
- Mongo写入安全机制
写入安全(Write Concern) 是一种客户端设置,用于控制写入的安全级别.默认况下,插入.删除和更新都会一直等待数据库响应(写入是否成功),然后才会继续执行.通常,遇到错误时,客户端会抛出一个 ...
- 乘风破浪,.Net Core遇见MAUI(.NET Multi-platform App UI),进击现代化跨设备应用框架
什么是MAUI https://github.com/dotnet/maui .NET Multi-platform App UI (MAUI) 的前身是Xamarin.Forms(适用于Androi ...
- 服务器通信REST、gRPC,Swagger/OpenAPI,Consul
服务间的通信方式是在采用微服务架构时需要做出一个最基本的决策.默认的选项是通过 HTTP 发送 JSON,也就是所谓的 REST API.我们也是从 REST 开始的,但最近我们决定改用 gRPC. ...
- Gitlab触发jenkins并获取项目post参数
jenkins -- Generic Webhook Trigger插件 此插件是git webhook的高阶应用,安装后会暴露出来一个公共API,GWT插件接收到 JSON 或 XML 的 HTTP ...
- Linux下使用Ansible处理批量操作
Ansible介绍: ansible是一款为类unix系统开发的自由开源的配置和自动化工具.它用python写成,类似于saltstack和puppet,但是不同点是ansible不需要再节点中安装任 ...