MySQL索引的使用,大大提升你代码的效率

目录

🚀索引使用

🚀最左前缀法则

 🚀范围查询

 🚀索引失效情况

隐式类型转换是什么?

隐式类型转换的影响

举例说明

无隐式类型转换的情况

存在隐式类型转换的情况

总结

🚀模糊查询

🚀or连接条件

🚀数据分布影响


🚀索引使用

验证索引效率

案例:这是一张有1000w的记录的表 (此案例来自黑马,我觉得黑马的案例很详细)

这张表中id为主键有主键索引而其他字段是没有建立索引的先来查询其中的一条记录看里面的字段情况,执行如下SQL

select * from tb_sku where id = 1\G;

 可以看到即使有1000w的数据,根据id进行数据查询,性能依然很快0.00sec为主键id是有索引的

下来,我们再来根据 sn字段进行查询执行如下SQL

SELECT * FROM  tb_sku  WHERE sn = '100000003145001 ';

我们可以看到根据sn字段进行查询查询返回了一条数据结果耗时  20.78sec就是因为sn没有索 引,而造成查询效率很低。

具体原因:首先,它没有使用索引。在没有索引的情况下,MySQL将扫描整个表来查找符合条件的行。这可能会导致性能下降,尤其是当表中的数据量很大时。

 我们可以针对于sn字段建立一个索引建立了索引之后我们再次根据sn进行查询再来看一 下查询耗时情况。

create  index  idx_sku_sn  on  tb_sku (sn) ;

然后再次执行相同的SQL语句再次查看SQL的耗时 

SELECT * FROM  tb_sku  WHERE sn = '100000003145001 ';

由此可以看出,建立了索引之后,查询的性能极大提升,因为MySQL可以使用索引来快速定位匹配的行,并进一步筛选符合额外条件的行。这将大大提高查询的效率,因为MySQL只需要访问少量的行来获取结果。

需要注意的是,索引并非在所有情况下都能提高查询性能。索引的选择和使用需要根据具体的数据和查询需求进行评估。过多或不必要的索引可能会增加写操作的开销,而且索引也需要占用额外的存储空间。因此,在设计和使用索引时,需要综合考虑查询频率、数据更新频率和存储成本等因素。

🚀最左前缀法则

show index from tb_user ; --显示tb_user表的索引

如果索引了多列(联合索引要遵守最左前缀法则最左前缀法则指的是查询从索引的最左列开始 并且不跳过索引中的列。如果跳跃某一列,索引将会部分失效(即面的字段索引失效)

 这些标记出来的是单链索引,主键id,phone,name,email

在  tb_user 表中有一个联合索引这个联合索引涉及到三个字段顺序分别为  profession age  status

对于最左前缀法则指的是查询时最左变的列也就是profession必须存在否则索引全部失效 而且中间不能跳过某一列,否则该列后面的字段索引将失效.

演示:

explain select * from tb_user where profession = '化工 ' and age = 38 and status
= '5 ';

 explain select * from tb_user where profession = '化工 ' and age = 38;

explain select * from tb_user where profession = '化工 ';    

 以上的这三组测试中,我们发现只要联合索引最左边的字段  profession索引就会生效只不 过索引的长度不同。    而且由以上三组测试,我们也可以推测出profession字段索引长度为47  age 字段索引长度为2  status字段索引长度为5

explain select * from tb_user where age = 38 and status = '5 ';

explain select * from tb_user where status = '5 ';

 而通过上面的这两组测试,我们也可以看到索引并未生效,原因是因为不满足最左前缀法则,联合索引 最左边的列profession不存在。

explain select * from tb_user where profession = '化工 ' and status = '5 ';

 上述的SQL查询时,存在profession字段,最左边的列是存在的,索引满足最左前缀法则的基本条   件。但是查询时,跳过了age这个列,所以后面的列索引是不会使用的,也就是索引部分生效,所以索 引的长度就是47。

 思考题:

当执行SQL语句 :

 explain select * from tb_user where age = 38 and   status = '0' and profession = '化工 '; 

是否满足最左前缀法则,走不走上述的联合索引,索引长度是多少?(也就是顺序换了之后还成不成立了)

可以看到,是完全满足最左前缀法则的,索引长度54联合索引是生效的

注意  :最左前缀法则中指的最左边的列,是指在查询时,联合索引的最左边的字段(即是

第一个字段)必须存在,与我们编写SQL时,条件编写的先后顺序无关。

 🚀范围查询

联合索引中,出现范围查询 (>,<)范围查询右侧的列索引失效

explain select * from tb_user where profession = '化工 ' and age > 30 and status
= '5 ';

当范围查询使用>   < 走联合索引了,但是索引的长度为49就说明范围查询右边的status段是没有走索引的。

explain select * from tb_user where profession = '化工 ' and age >= 30 and
status = '5 ';

当范围查询使用>=   <= 时,走联合索引但是索引的长度为54就说明所有的字段都是走索引的。所以,在条件允许的情况下,尽可能的使用类似于  >=   <= 这类的范围查询而避免使用  >   <

 🚀索引失效情况

索引列运算

不要在索引列上进行运算操作,索引将失效

tb_user表中除了前面介绍的联合索引之外还有一个索引phone字段的单列索引

当根据phone字段进行等值匹配查询时, 索引生效

explain select * from tb_user where phone = '17799990015 ';

 当根据phone段进行函数运算操作之后索引失效

explain  select  *  from  tb_user  where  substring (phone,10,2) = '15 ';

 字符串不加引号

字符串类型字段使用时,不加引号,索引将失效。

示例:加单引号与不加单引号的区别

explain select * from tb_user where profession = '化工 ' and age = 38 and status
= '5 ';

explain select * from tb_user where profession = '化工 ' and age = 38 and status
= 5 ;

explain select * from tb_user where phone = '17799990015 ';
explain select * from tb_user where phone = 17799990015;

 经过上面两组示例我们会明显的发现如果字符串不加单引号对于查询结果没什么影响但是数 据库存在隐式类型转换,索引将失效。

隐式类型转换是什么?

隐式类型转换是指在比较操作中,MySQL会自动将一个数据类型转换成另一个数据类型,以便进行比较。这种转换是在不明确指定的情况下自动发生的,用户不需要显式地进行类型转换操作。

隐式类型转换的影响

隐式类型转换可能导致索引失效,从而影响查询性能。当查询条件中的数据类型与列的数据类型不匹配时,MySQL会进行隐式类型转换,将查询条件的数据类型转换成列的数据类型进行比较。如果数据类型不匹配,MySQL可能无法充分利用索引,而是需要进行全表扫描来查找符合条件的行,导致性能下降。

举例说明

无隐式类型转换的情况

假设我们有一个名为users的表,包含以下列:

+----+---------+--------+
| id | name    | age    |
+----+---------+--------+
| 1  | Alice   | 25     |
| 2  | Bob     | 30     |
| 3  | Charlie | 35     |
| 4  | David   | 40     |
| 5  | Eve     | 45     |
+----+---------+--------+

如果我们对name列创建了索引,并执行以下查询:

SELECT * FROM users WHERE name = 'Alice';

由于查询条件中的数据类型与列的数据类型完全匹配,MySQL可以充分利用索引来快速定位和访问符合条件的数据,从而提高查询效率。

存在隐式类型转换的情况

现在假设我们对age列创建了索引,并执行以下查询:

SELECT * FROM users WHERE age = 30;

在这个例子中,由于查询条件中的数据类型与列的数据类型完全匹配,MySQL可以充分利用索引。

但是,如果我们执行以下查询:

SELECT * FROM users WHERE age = '30';

在这个例子中,查询条件中的数据类型是字符串,而列的数据类型是整数。MySQL将会进行隐式类型转换,将字符串转换成整数进行比较。这可能导致索引失效,从而影响查询性能。

总结

隐式类型转换可能导致索引失效,影响查询性能。为了避免这种情况,我们应该尽量确保查询条件中的数据类型与列的数据类型完全匹配,以充分利用索引提高查询效率。

🚀模糊查询

如果仅仅是尾部模糊匹配索引不会失效如果是头部模糊匹配索引失效

接下来我们来看一下这三条SQL语句的执行效果查看一下其执行计划

由于下面查询语句中,都是根据profession字段查询,符合最左前缀法则联合索引是可以生效的 我们主要看一下,模糊查询时,%加在关键字之前,和加在关键字之后的影响。

explain  select  *  from  tb_user  where  profession like '金属% '; 
explain  select  *  from  tb_user  where  profession like '%材料  ';
explain  select  *  from  tb_user  where  profession like '%材% ';

经过上述的测试,我们发现,在like模糊查询中,在关键字后面加%,索引可以生效。而如果在关键字前面加了%,索引将会失效。

🚀or连接条件

or分割开的条件,如果or前的条件中的列有索引,而后面的列中没有索那么涉及的索引都不会被用到。

explain select * from tb_user where id = 6 or age = 33;
explain select * from tb_user where phone = '15377777775 ' or age = 27;

第二个指令输出的结果很明显,只有phone有索引,后面的age没有索引,所以涉及的索引都不会用到,age没有索引所以即使id  phone有索引索引也会失效所以需要针对于age也要建立索引

然后,我们可以对age字段建立索引

create index idx_user_age on tb_user (age);

 建立了索引之后我们再次执行上述的SQL语句看看前后执行计划的变化

 最终我们发现or连接的条件左右两侧字段都有索引时索引才会生效

🚀数据分布影响

如果MySQL评估使用索引比全表更慢则不使用索引

select * from tb_user where phone >= '17799990005 ';
select * from tb_user where phone >= '17799990015 ';

经过测试我们发现相同的SQL语句只是传入的字段值不同最终的执行计划也完全不一这是为什么呢?

就是因为MySQL在查询时,会评估使用索引的效率与走全表扫描的效率,如果走全表扫描更快,则放弃索引,走全表扫描。因为索引是用来索引少量数据的,如果通过索引查询返回大批量的数据,则还不如走全表扫描来的快,此时索引就会失效。

我们再来看看  is null   is not null 操作是否走索引

执行如下两条语句 

explain select * from tb_user where profession is null;
explain select * from tb_user where profession is not null;

接下来我们做一个操作将profession字段值全部更新为null

update tb_user set profession = null ;

 然后,再次执行上述的两SQL查看SQL语句的执行计划

最终我们看到一模一样的SQL语句先后执行了两次结果查询计划是不一样的为什么会出现这种现象,这是和数据库的数据分布有关系,查询时MySQL会评估走索引快还是全表扫描快果全表 扫描更快,则放弃索引走全表扫描. 因此, is null is not null是否走索引,得具体情况具体分析,并不是固定的


希望对大家有帮助! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/422163.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【华为 ICT HCIA eNSP 习题汇总】——题目集7

1、一台 PC 的 MAC 地址是 5489-98FB-65D8 &#xff0c;管理员希望该 PC 从 DHCP 服务器获得指定的 IP 地址为192.168.1.11/24&#xff0c;以下命令配置正确的是&#xff08;&#xff09;。 A、dhcp static-bind ip-address 192.168.1.11 24 mac- address 5489-98FB-65D8 B、dh…

这个零售行业销售工具,老板都惊呆了!

在数字化时代&#xff0c;零售业正在经历一场深刻的变革&#xff0c;新零售模式逐渐成为业界的焦点。在这个变革的浪潮中&#xff0c;自动售货机以其智能、便捷的特性崭露头角&#xff0c;成为零售业的一项创新力量。 客户案例 零食自动售货机 福州某食品公司部署了泛地缘科技…

Android学习之路(22) ARouter原理解析

1.ARouter认知 首先我们从命名来看:ARouter翻译过来就是一个路由器。 官方定义&#xff1a; 一个用于帮助 Android App 进行组件化改造的框架 —— 支持模块间的路由、通信、解耦 那么什么是路由呢&#xff1f; 简单理解就是&#xff1a;一个公共平台转发系统 工作方式&…

7.12、中间人攻击(ARP欺骗)

一、ARP协议原理 地址解析协议(Address Resolution Protocol&#xff0c;ARP)&#xff0c;负责把目的主机的IP 地址解析成目的MAC地址&#xff0c;地址解析的目标就是发现逻辑地址与物理地址的映射关系。网络中的计算机、交换机、路由器等都会定期维护自己的ARP缓存表。 为什么…

ELK分离式日志(2)

目录 一.FilebeatELK 部署 开台服务器&#xff08;192.168.233.50&#xff09;下载fliebeat&#xff1a; 安装nginx后查看下日志文件&#xff1a; 设置 filebeat 的主配置文件: 关闭logstash&#xff0c;检测文件&#xff1a; 在50节点上启动filebeat&#xff1a; 访问页…

2、Line Charts折线图

可视化时间趋势 现在你已经熟悉了编码环境,是时候学习如何制作自己的图表了! 在本教程中,您将学习足够的Python来创建专业外观的折线图。然后,在接下来的练习中,您将使用您的最新技能处理真实世界的数据集。 本课程数据集夸克网盘下载链接:https://pan.quark.cn/s/a235ac…

Windows下RocketMQ搭建

RocketMQ安装 注&#xff1a;Windows必须先安装64bit的 JDK1.8 或以上版本及Maven 。 1.官网下载&#xff1a;下载 | RocketMQ 2.将下载下的安装文件解压到本地磁盘 3.配置环境变量 &#xff1a; 变量名&#xff1a;ROCKETMQ_HOME 变量值&#xff1a;G:\RocketMQ\rocketmq…

HCIA NAT练习

目录 实验拓扑 实验要求 实验步骤 1、IP分配 2、使用ACL使PC访问外网 3、缺省路由 4、边界路由器公网ip端口配置 测试 实验拓扑 实验要求 1、R2为ISP路由器&#xff0c;其上只能配置ip地址&#xff0c;不得再进行其他的任何配置 2、PC1-PC2可以ping通客户平板和DNS服…

[视频处理]关于视频处理的多画面样式

在开发视频系统时&#xff0c;经常会遇到多画面的需求&#xff0c;这里收集一些多画面的素材&#xff0c;共大家参考。 图片来源于网络&#xff0c;仅供参考。 后续补充文章 【图像处理】使用FPGA实现视频多画面的方案 多画面样式

springboot集成easypoi

easypoi,主打的功能就是容易,通过简单的配置&#xff0c;就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出 pom导入依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-star…

【C++】priority_queue模拟实现过程中值得注意的点

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 前言 本篇文章旨在记录博主在模…

【差分数组】【图论】【分类讨论】【整除以2】100213按距离统计房屋对数目

作者推荐 【动态规划】【数学】【C算法】18赛车 本文涉及知识点 差分数组 图论 分类讨论 整除以2 LeetCode100213按距离统计房屋对数目 给你三个 正整数 n 、x 和 y 。 在城市中&#xff0c;存在编号从 1 到 n 的房屋&#xff0c;由 n 条街道相连。对所有 1 < i < n…