MySQL优化慢SQL的6种方式

⛰️个人主页:     蒾酒

🔥系列专栏《mysql经验总结》

🌊山高路远,行路漫漫,终有归途


目录

写在前面

优化思路

优化方法

1.避免查询不必要的列

2.分页优化

3.索引优化

4.JOIN优化

5.排序优化

6.UNION 优化

写在最后


写在前面

本文介绍了MySQL常见的优化慢sql的手段,坚持看完相信对你有帮助。

同时欢迎订阅MySQL系列专栏,持续分享MySQL的使用经验。

优化思路

慢sql的优化无非是从两个方向着手

  • SQL语句本身的优化
  • 据库设计的优化

下面进行渐进式的分享一些常见优化手段

优化方法

1.避免查询不必要的列

查询应该精准的查出需要的列,对于select * 的写法要避免,因为所有字段查出来不仅sql查询执行慢,若是直接返回给前端,大量的数据也会影响网络传输效率。

2.分页优化

对于数据量特别大,这时分页会比较深,查询扫描的数据量会比较大效率自然低,我们就需要进行分页优化

假设我们有一个包含大量订单记录的订单表,其中每个订单都有一个唯一的不包含业务逻辑的主键,并且我们想要查询最近一个月的订单并按照订单id从小到大进行分页显示某页。

假设出现深分页的sql如下:

select * from orders where order_date >= date_sub(now(), interval 1 month)order by id limit 100000, 10;

执行此SQL时需要先扫描到100000行,然后再去取10行,但是随着扫描的记录数越多,SQL的性能就会越差,因为扫描的记录越多,MySQL需要扫描越多的数据来定位到具体的多少行,这样耗费大量的 IO 成本和时间成本。

对于解决该深分页问题通常有两种方法

1.延迟关联

先通过 where 条件提取出主键,在将该表与原数据表关联,通过主键 id 提取数据行,而不是通过原来的二级索引提取数据行

优化后sql:

select o.*
from (select idfrom orderswhere order_date >= date_sub(now(), interval 1 month)order by idlimit 100000, 10
) as sub
join orders as o on sub.id = o.id;

优化后SQL中的子查询只取主键id,可避免通过二级索引中的主键去回表查询,这样性能会快一些。

2.id偏移量

偏移量就是找到 limit 第一个参数对应的主键值,根据这个主键值再去过滤并 limit,这种方法又称为基于游标的分页。基于游标的分页的前提是需要保证主键或排序列的连续性、唯一性。

优化后sql:

select *
from orders
where id >= (select id from orders order by id limit 100000, 1)
order by id
limit 10;

这种方法相对于原来直接使用偏移量和限制结果数量的方式,可以在大数据集上提供更稳定和一致的性能,因为它不需要扫描和跳过大量的行

3.索引优化

通过合理的设计和使用索引,能够有效优化sql性能,这也是我们使用最多的手段。

下面介绍一下如何进行索引优化:

使用覆盖索引

InnoDB使用二级索引查询数据时会回表,但是如果索引的叶节点中已经包含要查询的字段,那它没有必要再回表查询了,这就叫覆盖索引,还有一个简单的理解查询列都是索引列

示例:

select product_name, price
from products
where category_id = 1;
create index idx_category_id on products (category_id, product_name, price);

避免使用or查询

在 MySQL 5.0 之前的版本要尽量避免使用 or 查询,可以使用 union 或者子查询来替代,因为早期的MySQL版本使用 or 查询可能会导致索引失效,高版本引入了索引合并,解决了这个问题,不过建议大家在实际使用中还是规范写法,能不用就少用。

避免使用 != 或者 <>操作符

SQL中,不等于操作符会导致查询引擎放弃查询索引,引起全表扫描,即使比较的字段上有索引。解决方法:通过把不等于操作符改成 or,可以使用索引,避免全表扫描

id <>'aaa'
id >'aaa'or id<'aaa

适当使用前缀索引

适当地使用前缀索引,可以降低索引的空间占用,提高索引的查询效率。比如,邮箱的后缀都是固定的“@xxx.com”,那么类似这种后面几位为固定值的字段就非常适合定义为前缀索引

create index idx_email_prefix on users (email(6)); -- 假设后缀长度为6

需要注意的是,前缀索引也存在缺点,MySQL无法利用前缀索引做 order by和 group by 操作,也无法作为覆盖索引。

避免列上函数运算

要避免在列字段上进行算术运算或其他表达式运算,否则可能会导致存储引擎无法正确使用索引,从而影响了查询的效率。

select order_id
from orders
where total_amount / 2 > 100

正确使用联合索引

使用联合索引的时候,注意最左匹配原则。 

4.JOIN优化

优化子查询

尽量使用 Join 语句来替代子査询,因为子査询是嵌套查询,而嵌套查询会新创建一张临时表,而临时表的创建与销毁会占用一定的系统资源以及花费一定的时间,同时对于返回结果集比较大的子查询,其对查询性能的影响更大 

小表驱动大表

关联查询的时候要拿小表去驱动大表,因为关联的时候,MySQL内部会遍历驱动表,再去连接被驱动表

select name from小表 left join 大表;

适当增加冗余字段

增加冗余字段可以减少大量的连表查询,因为多张表的连表查询性能很低,所有可以适当的增加冗余字段,以减少多张表的关联查询,这是以空间换时间的优化策略。

避免使用 JOIN 关联太多的表

《阿里巴巴 Java 开发手册》规定不要 join 超过三张表,第一join 太多降低査询的速度,第二 join 的buffer 会占用更多的内存。

5.排序优化

利用索引扫描做排序

MYSQL有两种方式生成有序结果:一是对结果集进行排序的操作,二是按照索引顺序扫描得出的结果,索引是排好序的数据结构,自然是有序的。
但是如果索引不能覆盖查询所需列(覆盖索引),就会每扫描一条记录回表查询一次(逐个获取),这个读操作是随机 IO,通常会比顺序全表扫描还慢,有时会直接放弃使用索引转为全表扫描。因此,在设计索引时,尽可能使用同一个索引既满足排序又用于查找行。

#索引为 a,b,c
select b,c from test where a like 'aa%' order by b,c;

只有当索引的列顺序和 ORDER BY 子句的顺序完全一致,并且所有列的排序方向都一样时,才能够使用索引来对结果做排序。

6.UNION 优化

条件下推

MySQL处理 union 的策略是先创建临时表,然后将各个查询结果填充到临时表中最后再来做查询,很多优化策略在 union 查询中都会失效,因为它无法利用索引。所以需要将 where、limit 等子句下推到 union 的各个子查询中,以便优化器可以充分利用这些条件进行优化。

此外,除非确实需要服务器去重,一定要使用 union all,如果不加 all 关键字,MySQL 会给临时表加上distinct 选项,这会导致对整个临时表做唯一性检查,代价很高。

写在最后

MySQL优化慢SQL的6种方式到这里就结束了,本文介绍了常见慢sql优化的有效方式。任何问题评论区或私信讨论,欢迎指正。

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

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

相关文章

无线网络2.4和5G的区别

无线网络2.4和5的区别 无线网络2.4GHz和5GHz的主要区别在于频率、覆盖范围、传输速度、干扰能力和穿透性。以下是详细介绍&#xff1a;12 频率不同。2.4GHz的频率较低&#xff0c;而5GHz的频率较高。频率越低&#xff0c;信号在传播过程中的损失越小&#xff0c;因此覆盖范围…

linux学习:文件属性

在操作文件的时候&#xff0c;经常需要获取文件的属性&#xff0c;比如类型、权限、大小、所有者等等&#xff0c; 这些信息对于比如文件的传输、管理等是必不可少的&#xff0c;而这些信息 这三个函数的功能完全一样&#xff0c;区别是&#xff1a;stat( )参数是一个文件的名字…

网络篇05 | 应用层 http/https

网络篇05 | 应用层 http/https 01 HTTP请求报文协议&#xff08;Request&#xff09;1&#xff09;Request简述2&#xff09;请求行&#xff08;首行&#xff09;3&#xff09;请求头&#xff08;Request Headers&#xff09;4&#xff09;空行5&#xff09;正文&#xff08;Re…

【机器学习300问】67、均方误差与交叉熵误差,两种损失函数的区别?

一、均方误差&#xff08;Mean Squared Error, MSE&#xff09; 假设你是一个教练&#xff0c;在指导学生射箭。每次射箭后&#xff0c;你可以测量子弹的落点距离靶心的差距&#xff08;误差&#xff09;。MSE就像是计算所以射击误差的平方后的平均值。它强调了每一次偏离靶心的…

ARM v8 Cortex R52内核 04 时钟和复位 Clocking and Resets

ARM v8 Cortex R52内核 04 时钟和复位 Clocking and Resets 4.1 Clock and clock enables 时钟和时钟使能 Cortex-R52处理器具有一个单一的时钟&#xff0c;驱动着所有的触发器和RAM。各种输入&#xff0c;包括复位输入&#xff0c;都有同步逻辑使它们可以与处理器时钟异步操…

如何在MacOS上使用OpenHarmony SDK交叉编译?

本文以cJSON三方库为例介绍如何通过OpenHarmony的SDK在Mac平台进行交叉编译。 环境准备 SDK准备 我们可以通过 openHarmony SDK 官方发布渠道下载对应mac版本的SDK&#xff0c;当前OpenHarmony MAC版本的SDK有2种&#xff0c;一种是x86架构&#xff0c;另一种是arm64&#x…

做一个后台项目的架构

后台架构的11个维度 架构1&#xff1a;团队协助基础工具链的选型和培训架构2&#xff1a;搭建微服务开发基础设施架构3&#xff1a;选择合适的RPC框架架构4&#xff1a;选择和搭建高可用的注册中心架构5&#xff1a;选择和搭建高可用的配置中心架构6&#xff1a;选择和搭建高性…

Hudi-ubuntu环境搭建

hudi-ubuntu环境搭建 运行 1.编译Hudi #1.把maven安装包上传到服务器 # 官网下载安装包 https://archive.apache.org/dist/maven/maven-3/ scp -r D:\Users\zh\Desktop\Hudi\compressedPackage\apache-maven-3.6.3-bin.tar.gz zhangheng10.8.4.212:/home/zhangheng/hudi/com…

Spring+SpringMVC的知识总结

一:技术体系架构二:SpringFramework介绍三:Spring loC容器和核心概念3.1 组件和组件管理的概念3.1.1什么是组件:3.1.2:我们的期待3.1.3Spring充当组件管理角色(IOC)3.1.4 Spring优势3.2 Spring Ioc容器和容器实现3.2.1普通和复杂容器3.2.2 SpringIOC的容器介绍3.2.3 Spring IOC…

字符串常量池(StringTable)

目录 String的基本特性 String的内存分配 字符串拼接操作 intern()的使用 String的基本特性 String&#xff1a;字符串&#xff0c;使用一对""引起来表示 String声明为final的&#xff0c;不可被继承 String实现了Serializable接口&#xff1a;表示字符串是支持…

考试酷基本功修炼课学习历程_FPGA成长篇

本文为明德扬原创文章&#xff0c;转载请注明出处&#xff01;作者&#xff1a;明德扬学员&#xff1a;考试酷账号&#xff1a;11167760 我是硬件工程师&#xff0c;日常工作中主要跟数字电路、模拟电路、嵌入式系统打交道&#xff0c;当然也会涉及到FPGA&#xff0c;但是苦于…

排序算法-基数排序

基数排序是一种非比较排序算法&#xff0c;它将待排序的数字按照位数进行排序。基数排序的思想是先按照个位数进行排序&#xff0c;然后按照十位数进行排序&#xff0c;接着按照百位数进行排序&#xff0c;以此类推&#xff0c;直到最高位排序完成。 基数排序的步骤如下&#x…

设计模式代码实战-桥接模式

1、问题描述 小明家有一个万能遥控器&#xff0c;能够支持多个品牌的电视。每个电视可以执行开机、关机和切换频道的操作&#xff0c;请你使用桥接模式模拟这个操作。 输入示例 6 0 2 1 2 0 4 0 3 1 4 1 3 输出示例 Sony TV is ON TCL TV is ON Switching Sony TV channel S…

【菜狗学前端】原生Ajax笔记(包含原生ajax的get/post传参方式、返回数据等)

这回图片少&#xff0c;给手动替换了~祝看得愉快&#xff0c;学的顺畅&#xff01;哈哈 一 原生ajax经典四步 (一) 原生ajax经典四步 第一步&#xff1a;创建网络请求的AJAX对象&#xff08;使用XMLHttpRequest&#xff09; JavaScript let xhr new XMLHttpRequest() 第二…

QQ农场-phpYeFarm添加数据教程

前置知识 plugin\qqfarm\core\data D:\study-project\testweb\upload\source\plugin\qqfarm\core\data 也就是plugin\qqfarm\core\data是一个缓存文件,如果更新农场数据后,必须要删除才可以 解决种子限制(必须要做才可以添加成功) 你不更改加入了id大于2000直接删除种子 D…

Vulnhub靶机 DC-2渗透详细过程

VulnHub靶机 DC-2 打靶 目录 VulnHub靶机 DC-2 打靶一、将靶机导入到虚拟机当中二、攻击方式主机发现端口扫描服务探针爆破目录web渗透信息收集扫描探针登录密码爆破SSH远程登录rbash提权 一、将靶机导入到虚拟机当中 靶机地址&#xff1a; https://www.vulnhub.com/entry/dc…

信息系统项目管理师0051:管理基础(4信息系统管理—4.1管理方法—4.1.1管理基础)

点击查看专栏目录 文章目录 第四章 信息系统管理4.1管理方法4.1.1管理基础1.层次结构2.系统管理第四章 信息系统管理 在信息技术和数据资源要素的推动下,社会各领域已经并正在加速进入数字化的全新发展时期,基于智能、网络和大数据的新经济业态正在形成,从“数字融合”向“数…

【Java虚拟机】三色标记、增量更新、原始快照、记忆集与卡表

三色标记、增量更新、原始快照、记忆集与卡表 三色标记基本原来错标、漏标错标漏标 增量更新基本原理写屏障 原始快照基本原理为什么G1使用原始快照而不用增量更新。 记忆集与卡表 三色标记 基本原来 三色标记是JVM的垃圾收集器用于标记对象是否存活的一种方法。 三色是指黑…

Servlet实现常用功能及其他方法

getParameter 获取body或url中指定的key/value值 String classIdreq.getParameter("classId"); getQueryString 获取请求的所有查询参数key,values1 String queryStringreq.getQueryString(); from表单提交 前端通过from表单提交用户名和密码 <!DOCTYPE htm…

Zookeeper和Kafka的部署

目录 一、Zookeeper的基本概念 1. Zookeeper定义 2. Zookeeper工作机制 3. Zookeeper特点 4. Zookeeper数据结构 5. Zookeeper应用场景 5.1 统一命名服务 5.2 统一配置管理 5.3 统一集群管理 5.4 服务器动态上下线 5.5 软负载均衡 6. Zookeeper 选举机制 6.1 第一…