sql优化的N种方法_持续更新

article/2025/9/18 6:17:08

       当你访问网站的时候,有的时候会慢的想让你砸电脑,这个时候服务器要背锅了吗? 不,要背锅的不仅仅是服务器,数据库也有很大责任,不负责任的sql开发者更会让你崩溃的.为了提高sql响应速度,还是好好了解下sql的优化吧

sql优化的方式

一:sql性能分析

sql优化首先要对sql的消耗时间,或者使用频率进行分析,然后在进行其他操作.具体性能分析请看我的另一篇博客

 MySQL进阶:sql性能分析_王会举的博客-CSDN博客

二:   explain关键字  

 使用explain关键字来查看当前sql语句的执行情况,来对症下药.因为内容较多,放在最后进行讲解

三:   正确的建立索引

索引的建立对sql的影响是非常大的,如果对索引不太理解的可以看我另一篇文章: ​​​MySQL进阶:索引的使用及理解_王会举的博客-CSDN博客_mysql索引的作用与使用  

select  * from user_test  WHERE uid=15988;
select  * from user_test  WHERE address=15988;  可以看到有索引的查找速度非常快.

四:剩下的就是零碎的对sql语句进行优化

3:SQL语句中IN包含的值不应过多:  

例如:select id from t where num in(1,2,3) 对于连续的数值,能用between就不要用in了; 实测速度差距不是很大.

4:SELECT语句务必指明字段名称:  

禁止用 * 来查询 ,禁止用 * 来查询 ,禁止用 * 来查询 , 查找哪个字段,就写具体的字段.

select  * from user_test  WHERE address=15988;
select  address from user_test  WHERE address=15988;

5:只查询一条数据的时候,使用limit 1

6:避免在where子句中对字段进行null值判断: 

对于null的判断会导致引擎放弃使用索引而进行全表扫描。(此处存在疑点,我本人测试的时候,发现索引还是能使用到)

更新:  mysql会自动判断数据的分布情况  判断数据中 null 多 还是 not null 多,   然后决定走不走索引.

explain select  uid from user_test  WHERE phone is null; 

7:避免在where子句中对字段进行表达式操作: 


select  uid from user_test  WHERE uid*10=40;
上面的sql对字段就行了算术运算,这会造成引擎放弃使用索引,建议改成:
select  uid from user_test  WHERE uid=40/10;

 

8:对于联合索引来说,要遵守最左前缀法则: 

例如组合索引(id,name,sex)  使用的时候,可以id 或者id,name .  禁止直接name,或者sex.会导致联合索引失败

注意: id, name,sex 这三个字段填写顺序不会有影响,  mysql会自动优化成最左匹配的顺序.

前三条sql都能命中索引,中间两条由于不符合最左匹配原则,索引失效. 

最后一条sql 由于有最左索引id 所以索引部分成功,部分失效.  id字段索引使用成功.

explain select * from  `user_test` where uid=10  ; 
explain select * from  `user_test` where uid=10 and name='张三'; 
explain select * from  `user_test` where uid=10 and name='张三' and phone='13527748096'; explain select * from  `user_test` where name='张三' and phone='13527748096'; 
explain select * from  `user_test` where name='张三'; explain select * from  `user_test` where uid=10 and phone='13527748096'; 

9: 尽量使用inner join,避免left join:

如果连接方式是inner join,在没有其他过滤条件的情况下MySQL会自动选择小表作为驱动表,但是left join在驱动表的选择上遵循的是左边驱动右边的原则,即left join左边的表名为驱动表。

10:注意范围查询语句: 

 对于联合索引来说,如果存在范围查询,比如between、> >= < <=等条件时,可能会造成后面的索引字段失效。索引失效是因为mysql发现全表扫描比走索引效率更高,因此就放弃了走索引
当Mysql发现通过索引扫描的行记录数超过全表的10%-30%时,优化器可能会放弃走索引,自动变成全表扫描。

explain select * from  `user_test` where uid=10 and name='张三' and phone='13527748096'; 
explain select * from  `user_test` where uid between( 1 and 10) and name ='张三' and phone='13527748096'; 
 

11:不建议使用%前缀模糊查询:

例如 : LIKE“%name”或者LIKE“%name%”,这种查询会导致索引失效而进行全表扫描。但是可以使用LIKE “name%”。

explain select * from  `user_test` where uid=10 and  uid like  "%1" ; 
explain select * from  `user_test` where uid=10 and  uid like  "1%" ; 

12:在 where 子句中使用 or 来连接条件,如果or连接的条件有一方没有索引,将导致引擎放弃使用索引而进行全表扫描

解决办法: 将or连接的双方都建立索引,就可以使用. 

explain select * from  `user_test` where  uid=10 or name='张三'; 

13:应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。(此处存在疑点,我本人测试的时候,发现索引还是能使用到)

explain select uid from  `user_test` where uid=1 and  substring(phone,1,3)='135'explain select uid from  `user_test` where uid=1 and   abs(uid)=1;

14: 字符串类型的字段 查询的时候如果不加引号''  ,会导致自动进行隐式转换,然后索引失效

15:指定查询的索引

当sql查询的字段有多个索引的时候,mysql优化器会自动选择一个索引进行查询,我们也可以通过sql字段进行自定义,

15.1: use index(索引): 推荐使用指定的索引  (最终用不用该索引,还需要mysql自己判断)

select * from  use index(索引A)  

15.2: ignore index(索引) : 忽略掉这个索引

select * from  ignore index(索引A)  

15.3: force index(索引): 强制使用该索引

select * from  force index(索引A)  

16: insert 优化

 16.1: 需要插入多条数据的时候 使用批量插入.(多次插入需要频繁的建立连接.浪费资源) 

 16.2: 多次插入数据时,采用手动提交事务

  sql语句在执行的时候如下所示, 会自动开启事务和提交事务.  我们可以手动开启事务,然后执行多条sql后,在手动提交事务.减少资源浪费.

start transaction;   执行sql;   commit;

 17: order by 排序优化 (排序时,使用有索引的字段进行排序)

使用order by排序时,会出现两种情况  (explain查看Extra字段)

1:using fileSort : 全表扫描,读取出数据,然后再排序缓冲区进行排序.  (排序字段没有索引)

2:using index: 通过索引直接返回有序的数据. 不需要额外排序(有索引,效率高)

18: count 优化     速度:count(*)>count(1)>count(字段)

 inndb引擎的使用如下  (MyIASM默认存了数据总数,所以效率最高)

1:count(字段):遍历整张表 会把每一行的字段值取出来,然后返回

2:count(1): 便利整张表,但不取值,对于返回的数据,放入1进去.然后累加

3:count(*):inndb引擎,特意做了优化,不会取出值,直接服务层进行累加

19:update优化  (避免出现表锁)

innodb引擎使用update时,会有行锁/表锁两种模式, 如果where 字段没有索引的时候会升级成表锁,

update table set xx=1 where  name=xx   (name没有索引,此时是表锁)
update table set xx=1 where  id=xx  (id有索引,此时是行锁)

20: 创建表时使用同一的编码

mysql多表联查时,如果表的字符集不一样,会有一个数据类型转换的过程.

例如 utf8 与utf8mb4前者是3字节unicode编码,后者是4字节unicode编码. 此时如果多表查询,则索引会失效

sql优化的语句将会持续更新,目前所知的就这些.

五: explain关键字分析:

    explain是非常重要的关键字,要善于运用它.  通过explain我们可以获得以下信息:

  • 表的读取顺序
  • 数据读取操作的操作类型
  • 哪些索引可以使用
  • 哪些索引被实际使用
  • 表之间的引用
  • 每张表有多少行被优化器查询

   使用方法:explain + sql语句。会出现下方截图.根据下方的字段来进行解析sql的问题所在

例如:  explain SELECT user_name FROM `user` WHERE id ="1060"

1:id字段:

 id可以认为是查询序列号,每一个id代表一个select,一句sql有两个select,就会有两列,两个id.,不同的id代表不同子查询,id越大优先级越高,越先被解析,如果id相同,则按照从上到下的顺序查找.

2:select_type:表示查询的类型

(1) SIMPLE(简单SELECT,不使用UNION或子查询等)(2) PRIMARY(子查询中最外层查询,查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY)(3) UNION(UNION中的第二个或后面的SELECT语句)(4) DEPENDENT UNION(UNION中的第二个或后面的SELECT语句,取决于外面的查询)(5) UNION RESULT(UNION的结果,union语句中第二个select开始后面所有select)(6) SUBQUERY(子查询中的第一个SELECT,结果不依赖于外部查询)(7) DEPENDENT SUBQUERY(子查询中的第一个SELECT,依赖于外部查询)(8) DERIVED(派生表的SELECT, FROM子句的子查询)(9) UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)

3:table:输出结果集的表

显示这一行的数据是关于哪张表的,有时不是真实的表名字,可能是简称

4:type:表示表的连接类型

对表访问方式,表示MySQL在表中找到所需行的方式,又称“访问类型”。常用的类型有: ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行index: Full Index Scan,index与ALL区别为index类型只遍历索引树range:只检索给定范围的行,使用一个索引来选择行ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用systemNULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。

5:possible_keys:表示查询时,可能使用的索引

指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用(该查询可以利用的索引,如果没有任何索引显示 null)

该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。
如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询

6:key:表示实际使用的索引

key列显示MySQL实际决定使用的键(索引),必然包含在possible_keys中

如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

7:key_len:索引字段的长度

表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的)

不损失精确性的情况下,长度越短越好 

8:ref:列与索引的比较

列与索引的比较,表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值


9:rows:扫描出的行数(估算的行数)

估算出结果集行数,表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数



10:Extra:执行情况的描述和说明

该列包含MySQL解决查询的详细信息,有以下几种情况:Using where:不用读取表中所有信息,仅通过索引就可以获取所需数据,这发生在对表的全部的请求列都是同一个索引的部分的时候,表示mysql服务器将在存储引擎检索行后再进行过滤Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询,常见 group by ; order byUsing filesort:当Query中包含 order by 操作,而且无法利用索引完成的排序操作称为“文件排序”-- 测试Extra的filesort
explain select * from emp order by name;
Using join buffer:改值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。Impossible where:这个值强调了where语句会导致没有符合条件的行(通过收集统计信息不可能存在结果)。Select tables optimized away:这个值意味着仅通过使用索引,优化器可能仅从聚合函数结果中返回一行No tables used:Query语句中使用from dual 或不含任何from子句-- explain select now() from dual;

explain关键字 转载至:MySQL Explain详解 - 杰克思勒(Jacksile) - 博客园 (博主写的非常棒)

参考文章: 史上最全SQL优化方案_ITPUB博客


http://chatgpt.dhexx.cn/article/3OF05GCb.shtml

相关文章

sql优化常用的几种方法:19种最有效的sql优化技巧

我们来谈谈项目中常用的MySQL优化方法&#xff0c;共19条&#xff0c;具体如下&#xff1a; 1、EXPLAIN 做MySQL优化&#xff0c;我们要善用EXPLAIN查看SQL执行计划。 下面来个简单的示例&#xff0c;标注&#xff08;1、2、3、4、5&#xff09;我们要重点关注的数据&#x…

sql优化的15个小技巧(必知五颗星),面试说出七八个就有了

目录 前言 1 避免使用select * 2 用union all代替union 3 小表驱动大表 4 批量操作 5 多用limit 6 in中值太多 7 增量查询 8 高效的分页 9 用连接查询代替子查询 10 join的表不宜过多 11 join时要注意 12 控制索引的数量 13 选择合理的字段类型 14 提升group by的…

MySQL高级篇(SQL优化、索引优化、锁机制、主从复制)

目录 0 存储引擎介绍1 SQL性能分析2 常见通用的JOIN查询SQL执行加载顺序七种JOIN写法 3 索引介绍3.1 索引是什么3.2 索引优劣势3.3 索引分类和建索引命令语句3.4 索引结构与检索原理3.5 哪些情况适合建索引3.6 哪些情况不适合建索引 4 性能分析4.1 性能分析前提知识4.2 Explain…

Sql优化总结!详细!(2021最新面试必问)

Sql优化 Sql执行顺序基础Sql优化查询SQL尽量不要使用select *&#xff0c;而是具体字段避免在where子句中使用or来连接条件使用varchar代替char尽量使用数值替代字符串类型查询尽量避免返回大量数据使用explain分析你SQL执行计划是否使用了索引及其扫描类型创建name字段的索引优…

如何破解VS2015(使用秘钥)

【时间】2018.10.07 【题目】如何破解VS2015&#xff08;使用秘钥&#xff09; 安装完vs2015 企业版/专业版后&#xff0c;在菜单帮助---注册产品&#xff0c;会显示产品试用期30天&#xff0c;怎么破解呢&#xff1f;其实只要输入相应的秘钥即可完成破解。如若不破解&#x…

vs2015激活码

microsoft visual studio2015是微软推出的一款集程序设计网页开发于一身的开发工具。microsoft visual studio 2015支持c,c,c#以及手机应用开发&#xff0c;用它所写的目标代码适用于微软支持的所有平台&#xff0c;包括Microsoft Windows、Windows Mobile、Windows CE、.NET F…

VS2017 激活密钥

【时间】2018.11.26 【题目】VS2017 激活密钥 一、激活秘钥 Enterprise[企业版]: NJVYC-BMHX2-G77MM-4XJMR-6Q8QF Professional[专业版]: KBJFW-NXHK6-W4WJM-CRMQB-G3CDH 二、秘钥使用 使用位置在 帮助 -- 注册商品 中&#xff1a; 输入秘钥后&#xff0c;激活成功后&a…

Android APP性能测试以及性能指标

Android的app性能测试包括的测试项&#xff1a;Activity响应时间&#xff0c;帧率,内存&#xff0c;cpu消耗,耗电量,冷启动 Activity响应时间的相关测试 查看当前APP打开的页面命令: adb shell dumpsys activity | findstr mResumedActivity然后用命令去打开APP的某个activ…

APP性能测试之GT 测试

APP性能测试之GT 测试 1 什么是 GT GT&#xff08;随身调&#xff09;是腾讯研发的开源 APP 随身调测平台&#xff0c;它是直接运行在手机上的“集 成调测环境”&#xff08;IDTE, Integrated Debug Environment&#xff09;。 GT 仅凭一部手机&#xff0c;无需连接电脑&a…

面试百问:如何测试App性能?

APP性能测试几乎是客户端面试必问。 为什么要做App性能测试 如果APP总是出现卡顿或网络延迟的情况&#xff0c;降低了用户的好感&#xff0c;用户可能会抛弃该App&#xff0c;换同类型的其他应用。如果APP的性能较好&#xff0c;用户体验高&#xff0c;使用起来丝滑顺畅&…

APP性能测试之IOS性能测试-instruments使用

最近在做APP的性能测试&#xff0c;已经在运行阶段&#xff0c;所以来总结下&#xff0c;本文章主要是讲的是IOS性能测试&#xff0c;我这边做的是内存漏洞分析和app启动时间/CPU占用/Core Animation等等&#xff0c;基本都试过了&#xff0c;说一下搭建过程吧 1.准备一个MAC电…

如何进行App性能测试?SoloPi是最佳选择!

目录 引言 SoloPi简介 SoloPi特点 SoloPi的主要功能 下载SoloPi 安装SoloPi 使用SoloPi进行性能测试 性能数据查看与记录 环境加压 响应耗时计算工具 注意事项 Solopi提供的各项性能指标介绍 引言 大家好&#xff01;我是凡哥。 今天我想跟你们分享一下如何进行A…

App性能测试以及测试方法技巧

性能专项我们关注哪些&#xff1a; 1.关注资源消耗&#xff08;CPU、内存、流量、功耗&#xff09; 2.启动耗时&#xff08;冷启、热启&#xff09;&#xff0c;&#xff08;这个也是很多云测时用到的一个指标&#xff09; 3.主要页面加载时间 4.内存泄漏、抖动、卡顿、页面渲染…

移动APP性能测试

移动APP性能测试 - 走看看 一、 App 性能指标 App 性能问题如 app 使用时卡顿严重或者加载页面慢&#xff0c;cpu 占用率高&#xff0c;app 闪退等&#xff0c;在测试过程中&#xff0c;则需特别关注性能方面的体验&#xff0c;app 性能差&#xff0c;通常会导致用户对 app 的…

如何进行app性能测试,app性能测试应关注的测试点

随着智能化生活的推进&#xff0c;我们生活中不可避免的要用到很多程序app。有的APP性能使用感很好&#xff0c;用户都愿意下载使用&#xff0c;而有的APP总是出现卡顿或网络延迟的情况&#xff0c;那必然就降低了用户的好感。所以APP性能测试对于软件开发方来说至关重要&#…

【项目】HTTP服务器

⭐️ 本博客介绍的是一个自主实现HTTP服务的一个项目&#xff0c;这要介绍的是项目实现的整个过程&#xff0c;用到的技术、遇到的问题以及都是如何解决的。想完成该项目&#xff0c;需要我们对HTTP有了解&#xff0c;这里可以查看我的往期博客——HTTP协议。这里还会用到流式套…

centos搭建http服务器

在虚拟机centos上搭建一个http服务器&#xff0c;端口号改为8080&#xff0c;并创建一个hello.html网页&#xff0c;网页的内容是自己的姓名拼音首字母&#xff0c;通过主机win10的浏览器访问这个页面&#xff0c; 步骤: 1.配置主机和虚拟机网络连通 2.在cent上通过yum指令安装…

http-server服务

实验简介&#xff1a; 两台在同一局域网的主机。机器A&#xff08;系统win10&#xff0c;IP地址为192.168.22.36&#xff09;&#xff0c;机器B。机器A中安装虚拟机win7系统&#xff0c;IP地址为192.168.41.130。 1. 安装node.js win7 无法使用node14版本及以上&#xff0c;以及…

web/http服务器实现

文章目录 项目开发流程程序编码项目实例 项目开发流程 需求分析&#xff1a;实现基本的HTTP服务器&#xff0c;支持浏览器的访问&#xff08;支持标准http协议&#xff09; 接收浏览器发送HTTP请求&#xff1b;解析请求数据&#xff0c;请求方式&#xff08;GET&#xff09;&a…

http服务-搭建简易的http服务器

##http服务-搭建简易的http服务器 仅仅实现了Post和Get,也就简单的使用了 200 OK,100-continue和发送http格式的文本而已&#xff0c;其实我们只要按照HTTP协议收发数据即可。 先来一张做http上传功能时的意外收获&#xff0c;也是待会的测试图片 浏览器访问我们所建立的链接 …