【MySQL】005 -- 深入浅出索引(下)
迪丽瓦拉
2025-05-28 17:25:25
0

    此文章为《MySQL 实战 45 讲》的学习笔记,其课程链接可参见:MySQL实战45讲_MySQL_数据库-极客时间

目录

一、索引(下)

1、覆盖索引

2、最左前缀原则

3、索引下推

4、思考题


满足语句需求的情况下, 尽量少地访问资源是数据库设计的重要原则之一

一、索引(下)

1、覆盖索引

在某些某些场景下,由于查询结果所需要的数据只在主键索引上有,所以不得不回表。

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

  

例如

如果执行的语句是select ID from T where k between 3 and 5,这时只需要查ID的值,而ID的值已经在k索引树上了,因此可以直接提供查询结果,不需要回表。也就是说,在这个查询里面,索引k已经“覆盖了”我们的查询需求,我们称为覆盖索引。

问题:那么基于上面的覆盖索引,在一个市民信息表上,是否有必要将身份证号和名字建立联合索引?

我们知道,身份证号是市民的唯一标识。也就是说,如果有根据身份证号查询市民信息的需求,我们只要在身份证号字段上建立索引就够了。但是如果现在有一个高频请求,要根据市民的身份证号查询他的姓名,这个联合索引就有意义了。它可以在这个高频请求上用到覆盖索引,不再需要回表查整行记录,减少语句的执行时间。

同时,索引字段的维护总是有代价的,在建立冗余索引来支持覆盖索引时就需要综合权衡考虑。

2、最左前缀原则

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

所谓最左原则指的就是如果你的 SQL 语句中用到了联合索引中的最左边的索引,那么这条 SQL 语句就可以利用这个联合索引去进行匹配;顾名思义,就是最左优先,在创建多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。值得注意的是,当遇到范围查询(>、<、between、like)就会停止匹配。

 联合索引的最左前缀匹配指的是:

Ⅰ、where条件一定要有联合索引的第一个字段;

Ⅱ、是否走联合索引与where条件的顺序无关,只与字段有关。

只要满足最左前缀,就可以利用索引来加速检索。这个最左前缀可以是联合索引的最左N个字段,也可以是字符串索引的最左M个字符。

问题:在建立联合索引的时候,如何安排索引内的字段顺序?

评估的标准是:索引的复用能力

第一原则是,如果通过调整顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的。

但是,如果既有联合查询,又有基于a、b各自的查询呢?查询条件里面只有b的语句,是无法使用(a,b)这个联合索引的,这时候你不得不维护另外一个索引,也就是说你需要同时维护(a,b)、(b) 这两个索引。

此时就需要考虑的原则就是空间了,

补充说明】:

联合索引相当于一个按照姓氏——名字的一个电话簿,只能先确定姓氏才可以命中索引。联合索引可以建立多列(列数大于2)的索引,建议列数最多不要越过3列,超过3列,应重新设计表。

更多内容可参考:[1] mysql的联合索引(复合索引) [2] 一文搞定联合索引

3、索引下推

最左前缀可以用于在索引中定位记录。那么,那些不符合最左前缀的部分,会怎么样呢?

以检索表中“名字第一个字是张,而且年龄是10岁的所有男孩”的SQL语句为例:

mysql> select * from tuser where name like '张%' and age=10 and ismale=1;

该语句在搜索索引树的时候,只能用 “张”,找到第一个满足条件的记录ID3,然后再判断其它条件是否满足:

  • 而MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。而有了索引下推优化,InnoDB在(name,age)索引再内部就判断了age是否等于10,对于不等于10的记录,直接判断并跳过,所以就只需要回表2。  
  • 在MySQL 5.6之前,只能从ID3开始一个个回表。到主键索引上找出数据行,再对比字段值。如下图所示,无索引下推优化的情况下,需要回表4。  

4、思考题

问题

实际上主键索引也是可以使用多个字段的。DBA小吕在入职新公司的时候,就发现自己接手维护的库里面,有这么一个表,表结构定义类似这样的:

CREATE TABLE `geek` (

  `a` int(11) NOT NULL,

  `b` int(11) NOT NULL,

  `c` int(11) NOT NULL,

  `d` int(11) NOT NULL,

  PRIMARY KEY (`a`,`b`),

  KEY `c` (`c`),

  KEY `ca` (`c`,`a`),

  KEY `cb` (`c`,`b`)

) ENGINE=InnoDB;

公司的同事告诉他说,由于历史原因,这个表需要a、b做联合主键,这个小吕理解了。

但是,学过本章内容的小吕又纳闷了,既然主键包含了a、b这两个字段,那意味着单独在字段c上创建一个索引,就已经包含了三个字段了呀,为什么要创建“ca”“cb”这两个索引?

同事告诉他,是因为他们的业务里面有这样的两种语句:

select * from geek where c=N order by a limit 1;

select * from geek where c=N order by b limit 1;

我给你的问题是,这位同事的解释对吗,为了这两个查询模式,这两个索引是否都是必须的?为什么呢?

答案:

表记录

–a--|–b--|–c--|–d--

1 2 3 d

1 3 2 d

1 4 3 d

2 1 3 d

2 2 2 d

2 3 4 d

主键 a,b的聚簇索引组织顺序相当于 order by a,b ,也就是先按a排序,再按b排序,c无序。

索引 ca 的组织是先按c排序,再按a排序,同时记录主键

–c--|–a--|–主键部分b-- (注意,这里不是ab,而是只有b)

2 1 3

2 2 2

3 1 2

3 1 4

3 2 1

4 2 3

这个跟索引c的数据是一模一样的。

索引 cb 的组织是先按c排序,在按b排序,同时记录主键

–c--|–b--|–主键部分a-- (同上)

2 2 2

2 3 1

3 1 2

3 2 1

3 4 1

4 3 2

所以,结论是ca可以去掉,cb需要保留

相关内容

热门资讯

linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
C++ 机房预约系统(六):学... 8、 学生模块 8.1 学生子菜单、登录和注销 实现步骤: 在Student.cpp的...
A.机器学习入门算法(三):基... 机器学习算法(三):K近邻(k-nearest neigh...
数字温湿度传感器DHT11模块... 模块实例https://blog.csdn.net/qq_38393591/article/deta...
有限元三角形单元的等效节点力 文章目录前言一、重新复习一下有限元三角形单元的理论1、三角形单元的形函数(Nÿ...
Redis 所有支持的数据结构... Redis 是一种开源的基于键值对存储的 NoSQL 数据库,支持多种数据结构。以下是...
win下pytorch安装—c... 安装目录一、cuda安装1.1、cuda版本选择1.2、下载安装二、cudnn安装三、pytorch...
MySQL基础-多表查询 文章目录MySQL基础-多表查询一、案例及引入1、基础概念2、笛卡尔积的理解二、多表查询的分类1、等...
keil调试专题篇 调试的前提是需要连接调试器比如STLINK。 然后点击菜单或者快捷图标均可进入调试模式。 如果前面...
MATLAB | 全网最详细网... 一篇超超超长,超超超全面网络图绘制教程,本篇基本能讲清楚所有绘制要点&#...
IHome主页 - 让你的浏览... 随着互联网的发展,人们越来越离不开浏览器了。每天上班、学习、娱乐,浏览器...
TCP 协议 一、TCP 协议概念 TCP即传输控制协议(Transmission Control ...
营业执照的经营范围有哪些 营业执照的经营范围有哪些 经营范围是指企业可以从事的生产经营与服务项目,是进行公司注册...
C++ 可变体(variant... 一、可变体(variant) 基础用法 Union的问题: 无法知道当前使用的类型是什...
血压计语音芯片,电子医疗设备声... 语音电子血压计是带有语音提示功能的电子血压计,测量前至测量结果全程语音播报࿰...
MySQL OCP888题解0... 文章目录1、原题1.1、英文原题1.2、答案2、题目解析2.1、题干解析2.2、选项解析3、知识点3...
【2023-Pytorch-检... (肆十二想说的一些话)Yolo这个系列我们已经更新了大概一年的时间,现在基本的流程也走走通了,包含数...
实战项目:保险行业用户分类 这里写目录标题1、项目介绍1.1 行业背景1.2 数据介绍2、代码实现导入数据探索数据处理列标签名异...
记录--我在前端干工地(thr... 这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前段时间接触了Th...
43 openEuler搭建A... 文章目录43 openEuler搭建Apache服务器-配置文件说明和管理模块43.1 配置文件说明...