深入理解mysql性能优化以及解决慢查询问题

news2025/1/12 1:40:52

MySql系列整体栏目


内容链接地址
【一】深入理解mysql索引本质https://blog.csdn.net/zhenghuishengq/article/details/121027025
【二】深入理解mysql索引优化以及explain关键字https://blog.csdn.net/zhenghuishengq/article/details/124552080
【三】深入理解mysql的索引分类,覆盖索引(失效),回表,MRRhttps://blog.csdn.net/zhenghuishengq/article/details/128273593
【四】深入理解mysql事务本质https://blog.csdn.net/zhenghuishengq/article/details/127753772
【五】深入理解mvcc机制https://blog.csdn.net/zhenghuishengq/article/details/127889365
【六】深入理解mysql的内核查询成本计算https://blog.csdn.net/zhenghuishengq/article/details/128820477
【七】深入理解mysql性能优化以及解决慢查询问题https://blog.csdn.net/zhenghuishengq/article/details/128854433
【八】深入理解mysql执行的底层机制https://blog.csdn.net/zhenghuishengq/article/details/128100377
【九】深入理解mysql集群的高可用机制https://blog.csdn.net/zhenghuishengq/article/details/126239652

深入理解mysql的性能优化

  • 一,mysql的性能优化
    • 1,mysql调优的基本思路
    • 2,慢查询优化
      • 2.1,慢查询日志的基本使用
      • 2.2,对慢查询进行优化
        • 2.2.1,在业务层中-是否请求了不需要的数据
        • 2.2.2,在执行层中-是否存在扫描额外的记录
      • 2.3,慢查询的重构
        • 2.3.1,将一个复杂查询拆分成多个简单查询
        • 2.3.2,切分查询
        • 2.3.3,分解关联查询
    • 3,通过mysql的执行流程考虑性能优化
      • 3.1,查询速度慢的原因
      • 3.2,show profile使用(了解)
    • 4,mysql查询优化规则
      • 4.1,条件简化
      • 4.2,外连接消除
      • 4.3,子查询优化
        • 4.3.1,子查询优化规则

一,mysql的性能优化

1,mysql调优的基本思路

在mysql性能优化中,存在一个调优的金字塔,如下图所示。

在这里插入图片描述

主要有硬件和OS调优,MySql调优和架构调优这三种,并且越往上他的成本就越来越高,越往下他的效果就越来越好。如磁盘调优可以将机械硬盘换成SSD硬盘;架构调优可以进行分库分表,读写分离,并且可以在最初的系统设计时,可以根据业务来选择使用一些中间件,如redis,es,hbase等;MySql调优就是对一些sql语句,如添加索引,所有等进行调优。

2,慢查询优化

2.1,慢查询日志的基本使用

慢查询日志,指的就是mysql记录所有执行超过 long_query_time 参数设定的时间阈值的SQL语句的日志。默认情况下,慢查询日志是关闭的,因此如果要使用上这个慢查询日志,那么就需要开启这个慢查询日志的功能。

show VARIABLES like 'slow_query_log'; 

通过上面这条命令来查询当前mysql的慢查询日志功能是否开启,如果没有开启,那么就通过下面这条命令来开启

//开启慢查询日志功能
set GLOBAL slow_query_log = 1;

接下来可以查看这个慢查询日志的这个时间阈值,该值默认是10s,这个值也可以进行一个修改。当查询的语句的时间超过10s时,那么就会将该语句记录到日志中。

show VARIABLES like '%long_query_time%'; 

在这里插入图片描述

对于这个慢查询产生的日志,一般是存储在这个table和file中,最好是存储在这个file文件中,因为放表的话会影响mysql的执行效率,并且这个日志文件一般是存储在这个data的目录下

show VARIABLES like 'log_output'; 

2.2,对慢查询进行优化

在开启这个慢查询日志之后,在超过这个10s的阈值时,这条sql就会添加到这个慢查询的日志里面,那么就可以通过这些日志文件查看哪些sql语句的执行效率比较低,然后再分析这些sql的效率低下的原因。在查看文件中的日志时,可以借助这个慢查询的辅助工具mysqldumpslow来对这些日志进行分析,并且可以通过这个辅助工具进行一个快速定位。

mysqldumpslow -s r -t 10 slow-mysql.log

在使用这个工具时,其伴有以下几个参数:

-s order (c,t,l,r,at,al,ar)
    c:总次数
    t:总时间
    l:锁的时间
    r:获取结果的行数
    at:平均数
    -s:排序
    -t:NUM,仅显示前n条数据
    -g:筛选数据

在分析这个慢sql时,主要通过以下的几个方法和思路来进行sql的优化:

2.2.1,在业务层中-是否请求了不需要的数据

1,是否查询了不需要的记录,如只需要获取最早创建的时间的数据,但是确实直接获取了全部数据,在内存中获取最小的时间,这样将其他查询出来的数据全部不要,这样就会让整个sql相对来说比较慢

2,总是取出全部的列,如果时只需要查询少量的字段,那么就杜绝这个select * 的使用,并且这样也可以防止覆盖索引的失效问题。但是需要在数据缓存的时候,还是需要写select * 的

3,重复查询相同的数据,如在一个for循环中,每循环一次都是使用一个sql查询,这样就可以将这个查询放在这个循环的外面。或者直接加入到缓存中,后面直接去缓存中获取数据

2.2.2,在执行层中-是否存在扫描额外的记录

1,响应时间,通过具体的响应时间来判断是否存在额外扫描,如是否出现大量数据的网络传输,加行锁的情况

2,扫描的行数和返回的行数,这个如典型的limit,会先将全部数据查出来,然后取10条,将其他的数据全部弃掉

3,扫描的行数和返回的类型,如通过这个explain来具体分析,通过这个type来确认这个索引的类型等,这个主要是通过这个索引,因为索引可以让 MySQL以最高效、扫描行数最少的方式找到需要的记录。

在SQL语句中常见的WHERE条件,一般有三种方式,其从好到坏依次如下:

1,在索引中直接使用where条件过滤掉不匹配的数据,直接在这个引擎层完成。

2,使用覆盖索引扫描返回记录,即在Extra字段出现这个Using index时,直接从索引中过滤掉不需要的记录并返回命中的结果,直接在server层将数据返回。

3,从数据表中返回数据,在Extra这个字段出现这个Using Where时,直接在mysql的server层完成,但是需要从表中将数据读取中,然后在对这些数据进行过滤。

2.3,慢查询的重构

在发现了慢查询时,那么就需要对这个慢查询进行一个重构,其重构的思路主要有如下几种

2.3.1,将一个复杂查询拆分成多个简单查询

如存在一写条件判定,如下这种,并且存在多个这种条件判断,如果全部挤在一个sql语句中,当数据量很大时,这些业务判断逻辑如果强行加在这个mysql身上,那么就会很大的程度上影响这个sql的查询效率。

if ... then ... else if ... then ... else

这样就可以去拆分这个复杂的查询,第一个if后面做一次查询,第二个做一次查询。如查询三个年龄段的用户,如果强行在一个sql中将数据全部查出来,那么效率肯定会很低,甚至可能因为范围查询出现这个联合索失效的问题,那么就可以将这个复杂的查询拆分成三个sql语句来查询了。当然这里最好时根据具体的业务需求来决定是复杂查询还是简单查询。

2.3.2,切分查询

在数据量大的情况下,如果想一次性将所有数据全部查出,然后在对查出的数据做一个修改,那么效率肯定会特别的慢,甚至可能会引发很多锁表,耗尽系统资源的问题。那么就需要利用这个切分的概念,将大数据拆分成小数据,每次查询只完成一部分数据,从而解决慢查询的问题。如开启一个定时任务,每一分钟完成1000条数据。

2.3.3,分解关联查询

在使用这个连接查询时,可以通过这个分解这个连接查询,来提高这个查询效率。如在拆分之后,可以直接走缓存来获取结果。分解之后的的代码也可以实现复用,更容易的做到高性能和高扩展。

3,通过mysql的执行流程考虑性能优化

3.1,查询速度慢的原因

其基本流程就是建立连接,语法分析器分析,优化器优化,执行器执行,最后将结果集返回给客户端

查询需要在不同的地方花费时间,包括网络,CPU计算,生成统计信息和执行计划、锁等待(互斥等待)等操作,尤其是向底层存储引擎检索数据的调用操作,这些调用需要在内存操作,CPU操作和内存不足时导致的IO操作上消耗时间。

如在查询出10w条数据的时候,要将结果集返回给客户端,那么其网络传输就需要部分时间;在加载数据驱动时,也需要一部分时间去加载这个驱动Driver,也需要部分时间;用户认证,语义分析,索引优化等,都需要时间。

除了这些情况之外,还要判断线程的数量,如果线程数太多,导致进程的上下文切换,也会对查询速度有一定的影响。

3.2,show profile使用(了解)

在使用这个慢查询工具依旧不能分析出这个具体的结果的时候,那么就可以通过这个 show profile 来分析这个线程到底时间花在哪里。

show profiles;

然后找到具体的mysql的位置,如在1这个位置,然后直接定位到1这个位置

show profile for query 1; 或者
show profile for all query 1;

其结果如下,其具体的值也可以从mysql的官方文档中有详细的描述。

在这里插入图片描述

4,mysql查询优化规则

4.1,条件简化

如存在一些 1=1时,mysql会自动将这些简化忽视;还有如一些 a = 5 and b > a这种条件,会简化成 a = 5 and b > 5等等。

4.2,外连接消除

由于内连接和外连接最大的区别就是这个sql补齐的问题,外连接会自动补null值,内连接只查出符合条件的sql。

select * from e1 inner join e2 on e1.name = e2.name
select * from e1 left  join e2 on e1.name = e2.name

在使用这个内连接的时候,mysql内部会对这几张表做一个成本计算,会去判断一下使用哪张表作为这个驱动表的这个成本低一些,然后再根据具体的成本比较再决定选择谁作为驱动表。而使用这个外连接时,mysql默认认为from后面的表就是驱动表,join后面的表就是被驱动表,其驱动表和被驱动表的位置是固定的,那么这个mysql也不会对这个外连接做一个成本计算的优化。

因此在使用这个外连接时,可以考虑增加一个where条件,过滤掉这些被驱动表数据为null的值,因此可以将上面的left join连接查询的sql语句改写成如下:

select * from e1 left  join e2 on e1.name = e2.name where e2 is not null

这样被驱动表数据为空的数据就直接被过滤掉了,mysql就会默认的将这个值优化成内连接,这样mysql就可以根据内部的成本计算,来选择哪张表作为这个驱动表,哪张表作为这个驱动表了,这样就可以实现这个外连接消除。

4.3,子查询优化

子查询的基本语法如下

select (select name from teacher limit 1);
select name,age from (select name,age + 1 from teacher) as t;
select * from student where age in (select age-20 as age from teacher where age < 50);

在优化这个子查询的过程中,需要先判断这条sql语句的外部查询和子查询的两张表是否相关

//不相关子查询
select * from student where age in (select age-20 as age from teacher);
//相关子查询
select * from student where age in (select age-20 as age from teacher where student.class_id = teacher.class_id);

不相关就是直接先查内部的子查询,后面将参数代入到整个外部查询中;相关就是先查外部的sql语句,每查出一条数据,就代入到子查询中进行匹配,看是否满足其内部的规则。

4.3.1,子查询优化规则

再来分析这个不相关的子查询,其sql如下:

select * from student where age in (select age-20 from teacher where class_id = 1);

这里需要考虑的问题就是,在这个子查询中,可能会查询出几千甚至几万条数据,这样作为参数给前面的sql语句,首先就是效率比较慢,其实很有可能会让这个服务器内存放不下;并且在使用这个in时,mysql很有可能无法使用到索引,从而走全表扫描。

因此mysql主要的内部的优化方式就是将这个子查询作为一个临时表,然后进行一个联表查询来获取数据。并且可以给这个临时表建索引,去重等操作,或者将这些数据加入到memory的内存中,从而提高查询效率。这种表被称为物化表

而在这个物化表的基础之上,就是在建立临时表的基础上,将这个子查询再优化成这个连接查询,并且优化成内连接的连接查询,这样就在之前的物化表的基础之上提升了效率,这种优化方式被称为半连接,即semi-join

再分析一个表相关的子查询,其sql如下:

select * from student where age in (select age-20 as age from teacher where student.class_id = teacher.class_id);

这张表上是有索引的,但是不一定会使用到索引,mysql内部就会通过改变这个in关键字,将这个in改写成exists这个关键字,从而让这个字段走索引。不管子查询是相关的还是不相关的,都尝试可以使用这个exists替换in,从而解决这个in索引失效的问题。当然直接在外部直接使用这个exists关键字,这样就可以省去mysql内部转换的时间,从而增加查询效率。

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

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

相关文章

GPT1、GPT2、GPT3原理

一 背景 GPT1:Generative Pre-Training。是一种生成式的预训练模型,由OpenAi团队发表自论文《Improving Language Understanding by Generative Pre-Training》。 h0=UWe+Wp 二 模型整体结构(宏观) 图1 GPT整体结构 左侧为模型的整体结构,由12个Transformer中的Decoder模块…

App的分类与简析

引言随着智能手机的普及&#xff0c;移动端应用几乎成为每个互联网产品的标配。在快速迭代的互联网战场中高效开发、低成本上线产品&#xff0c;是每个应用开发团队追求的目标。此时&#xff0c;选择合适的应用类型和开发模式便至关重要。移动应用可以粗分为三种&#xff1a;原…

Hystrix线程池隔离与接口限流

前面了解了Hystrix的请求缓存、fallback降级、circuit breaker断路器快速熔断,下面来看下Hystrix的线程池隔离与接口限流。 Hystrix通过判断线程池或者信号量是否已满,超出容量的请求,直接Reject走降级,从而达到限流的作用。限流是限制对后端服务的访问量,比如对MySQL、Re…

CentOS7 LVM 逻辑卷2种读写策略(磁盘IO性能优化)—— 筑梦之路

LVM 逻辑卷的读写策略有两种&#xff1a; linear&#xff1a;线性方式&#xff0c;一块块盘来读写&#xff0c;写完一块盘再写第二块盘、第 N 块盘&#xff0c;性能低striped&#xff1a;条带方式&#xff0c;多块盘一起并行读写&#xff0c;性能高查看 LVM 逻辑卷的读写策略的…

元宇宙,会成为下一代互联网的主场吗?

导语 | 2022 年元宇宙风靡全网&#xff0c;作为过去一年科技界的“当红扛把子”&#xff0c;引多家科技巨头“竞折腰”。近日&#xff0c;《福布斯》双周刊网站在报道中指出&#xff0c;2030 年全球元宇宙的市场规模有望高达 5 万亿美元&#xff0c;2023 年可能是确定其发展方向…

机器学习0 — 总体架构,chatgpt时代必须掌握的

1 从chatgpt看目前AI重要性 随着chatgpt的一声巨响&#xff0c;拉响了强人工智能的序幕。chatgpt相对于目前的各种机器人&#xff0c;简直就是弓箭和导弹的区别。沉寂了两三年后&#xff0c;AI如今又一次站在了人类工业的最高舞台。个人认为AI已经成为所有人&#xff0c;特别是…

vitest第二章(入门)

Vitest 是一个由 Vite 提供支持的极速单元测试框架 tips vite>3 node>14 安装 1.使用npm init -y 生成 package json 2.安装依赖 挑选一种即可 npm install -D vitestyarn add -D vitestpnpm add -D vitest3.新建一个文件calc.ts 开始第一个单元测试吧&#xff0c;…

【数据结构和算法】使用数组的结构实现链表(单向或双向)

上文我们通过结构体的结构实现了队列、以及循环队列的实现&#xff0c;我们或许在其他老师的教学中&#xff0c;只学到了用结构体的形式来实现链表、队列、栈等数据结构&#xff0c;本文我想告诉你的是&#xff0c;我们可以使用数组的结构实现链表、单调栈、单调队列 目录 前言…

2022最火科技~AIGC

2022年最火的信息科技~AIGC 人工智能内容生成 趣讲大白话&#xff1a;输入几个词&#xff0c;立刻生成机器创造的内容 ************** 从人工智能决策 走向 人工智能生成 人工智能决策&#xff1a;自动驾驶、抖音推荐算法 人工智能生成内容&#xff1a;即AI Generated Conten…

【算法练习】两个链表的第一个公共节点

描述输入两个无环的单向链表&#xff0c;找出它们的第一个公共结点&#xff0c;如果没有公共节点则返回空。&#xff08;注意因为传入数据是链表&#xff0c;所以错误测试数据的提示是用其他方式显示的&#xff0c;保证传入数据是正确的&#xff09;数据范围&#xff1a; 0n≤1…

下一代编解码技术Ali266在视频超高清领域的应用展望

超高清与各领域的需求融合和创新正在发生。 2022年是一个体育大年&#xff0c;众多世界级体育赛事通过视频直播、转播等形式给观众带来畅爽的观看体验。 2022年北京冬奥会&#xff0c;实现了奥运会历史上首次赛事全程4K制作播出&#xff0c;并在开幕式上提供了8K超高清公共信号…

安全多方计算之五:零知识证明(从入门到入土。。)

零知识证明1. 简介2. 零知识证明的例子2.1 向红绿色盲证明红球、绿球2.2 数独的零知识证明2.3 三染色问题的零知识证明2.4 Quisquater-Guillou 零知识协议3. ElGamal加密的零知识证明3.1 ElGamal加密的已知明文证明3.2 ElGamal加密的二选一零知识证明3.3 ElGamal加密的1-out-of…

MATLAB - 查找数据峰值

语法如下&#xff1a; pks findpeaks(data) [pks,locs] findpeaks(data) [pks,locs,w,p] findpeaks(data) [___] findpeaks(data,x) [___] findpeaks(data,Fs) [___] findpeaks(___,Name,Value) findpeaks(___)where&#xff0c;pks是峰值返回值&#xff0c;locs是数据索…

特斯拉 FSD 背后的技术(1)—从 BEV 到占用网络

在今年 tesla 的 AI Day 给我这个业余自动驾驶爱好者给留下了深刻印象&#xff0c;在看过之后&#xff0c;通过收集资料对其中阐述的技术进行简单的了解&#xff0c;在这里拿出来跟大家分享一下&#xff0c;有点长&#xff0c;所以划分了一下 3 个部分。从 BEV 到占用网络激进无…

chrome查看网页性能

1 Performance 1.1 打开开发者工具&#xff08;cmdshiftc&#xff09; 1.2 打开Performance面板&#xff0c;点击录制按钮&#xff08;开始录制&#xff09; 1.3 刷新页面&#xff0c;再次点击录制按钮&#xff08;结束录制&#xff09; 录制按钮高亮&#xff0c;表示录制中…

算法训练营DAY47|198.打家劫舍、213.打家劫舍II 、337.打家劫舍III

这一期到了打家劫舍的专题&#xff0c;说是专题但实际上只有一期&#xff0c;而且只有三道题&#xff0c;我们把这三道题放在一起讲&#xff0c;第一道题简单一些&#xff0c;后两道略有不同方向上的难度。但总体来看第一次做可能有一点难想到思路&#xff0c;其实代码实现还是…

百度、字节终于不再相互“抄袭”

文|智能相对论作者|佘凯文“百度和字节跳动&#xff0c;分道扬镳”乍一看挺标题党的&#xff0c;这两个互联网巨头从没在一起过&#xff0c;又何来“分道扬镳”之说&#xff1f;不急&#xff0c;且往下看。众所周知&#xff0c;当前国内互联网行业&#xff0c;早已不是当初啥也…

【链表->环形链表】

诸如环形链表的结构有&#xff1a;尾节点链接向各个节点的链表&#xff0c;也可链向自己&#xff0c;称为环形链表。只要链表中带有环&#xff0c;均可称为环形链表。下面通过一些例题来详细讲述环形链表&#xff1a;1.给你一个链表的头节点 head &#xff0c;判断链表中是否有…

python进阶——人工智能实时目标跟踪

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a;lqj_本人的博客_CSDN博客-微信小程序,前端,vue领域博主lqj_本人擅长微信小程序,前端,vue,等方面的知识https://blog.csdn.net/lbcyllqj?spm1000.2115.3001.5343 哔哩哔哩欢迎关注&…

Apollo planning之参考线平滑算法

Apollo studio 官网&#xff1a;Apollo开发者社区 (baidu.com) 目录 1 参考线的作用 2 参考线的数据结构 2.1 ReferenceLine的数据结构 2.2 ReferencePoint的数据结构 3 参考线处理流程 ​4 参考线平滑算法 4.1 算法分类 4.2 参考线平滑算法流程 4.2.1 AnchorPoint …