MySQL 45 讲学习笔记 ☞ 05 深入浅出索引(下) @ FnEsc | 2021-07-12T14:26:13+08:00 | 2 分钟阅读

通过索引搜索,查询数据过程?

回表

给定下面一个表,执行 select * from T where k between 3 and 5 语句,索引树的搜索过程是怎样的?

mysql> create table T (
    ID int primary key,
    k int NOT NULL DEFAULT 0, 
    s varchar(16) NOT NULL DEFAULT '',
    index k(k)
)
engine=InnoDB;
 
insert into T values(100,1, 'aa'),(200,2,'bb'),(300,3,'cc'),(500,5,'ee'),(600,6,'ff'),(700,7,'gg');

从表构造上看,索引搜索树是这样的:

T 表索引搜索树

然后这条 SQL 查询语句的执行流程是这样的:

  1. 在 k 索引树上找到 k=3 的记录,取得 ID = 300;
  2. 再到 ID 索引树查到 ID=300 对应的 R3;
  3. 在 k 索引树取下一个值 k=5,取得 ID=500;
  4. 再回到 ID 索引树查到 ID=500 对应的 R4;
  5. 在 k 索引树取下一个值 k=6,不满足条件,循环结束。

在这个过程中,回到主键索引树搜索的过程,我们称为回表

覆盖索引

假如上述执行的 SQL 语句是这样的呢? select ID from T where k between 3 and 5

这里只需查询 id 的值,而这个值已经在 k 索引树上了,因此可以直接提供查询结果,不需要回表,这样的话成为覆盖索引。

由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。

在一个市民信息表上,是否有必要将身份证号和名字建立联合索引?答:正常身份证号是唯一标识,在该字段上做索引就好了。如果有高频请求根据身份证查姓名,则建立该联合索引(不需回表)。

最左前缀原则

像 B+ 树这种索引结构,可以利用索引的“最左前缀”,来定位记录。

如当在一个市民信息表上做了 (name, age) 做了联合索引:

  • 当条件查询 where name = '张三' 的时候,索引快速定位。
  • 当条件查询 where name like '张 %' 的时候,这时候也能用上这个联合索引,找到第一个符合条件的记录,然后向后遍历,直到不满足条件为止。

显然,最左前缀原则的基础上,当已经有了 (a, b) 这个联合索引后,一般就不需要单独在 a 上建立索引了。(别忘了建立索引还需要考虑空间)

索引下推

MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在索引遍历过程中,对索引内部中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。

© 2021 FnEsc Hugo Site

Powered by Hugo with theme Dream.

avatar

FnEsc 的博客一边担心未来,一边浪费现在。

关于我

FnEsc 的 💜 博客

自从 2021.07 开始搭建该 hugo 博客,作为记录一些生活/技术上的小笔记

2020届应届生,毕业与佛山科学技术学院计算机科学与技术专业

目前职业是 全栈开发程序🐶 打杂工具人

作为传统行业外企电商的 965,使我并没有很勤奋卷

不想那么相关工作为 SAP Fiori 应用开发和维护。

目前主要的技术栈是:

  • Python Web 端架构
  • Django / Odoo 开发

接下来可能想学习的方向是:

  • Python 进阶(流畅的 python)
  • MySQL 知识巩固(MySQL 实战 45 讲)
  • Go 开始学习(Go 语言核心 36 讲)
  • 其他架构/算法尝试学习
社交链接