(四)、MySQL查询优化

《高性能MySQL》第三版,第六章学习笔记

一、优化数据的访问

        查询性能低下最基本的原因是访问的数据太多。可以通过下列两个步骤进行分析:

1、确认应用程序是否在检索大量超过需要的数据。这通常意味着访问了太多的行,但雨哦时候也可能访问了太多的列。

2、确认MySQL服务器是否在分析大量超过需要的数据行。

1、是否请求了不需要的数据

        有些查询会请求超过实际需要的数据,然后这些多余的数据会被应用程序丢弃,这会带来额外的负担和网络开销。
        一些案例:

        1、查询不需要的记录
             如果在页面展示中只需要10条记录,可以把分页操作直接在后端进行,在查询语句后面
        添加limit,就只返回需要的10条数据,而不是把数据全部返回到前端,在前端进行分页操作,
        在丢弃其他不需要的数据。

        2、多表关联时返回全部列
              在关联查询是最终返回的列尽量不要使用“ * "代替,这会返回所有关联表的列。尽量返回
        需要的列

        3、总是取出全部的列
             与第二点类似,单表查询时在写” * “时,需要考虑是否真的需要全部列。

        4、重复查询相同的数据
             对于一些不经常更改的数据,可以在第一次查询出来后就缓存到前端(浏览器)或者后端,
        当在其他地方引用此数据时,可以直接到缓存中取就行,就不用再执行SQL查询、发送接口
        等不必要的重复操作。

2、是否在扫描额外的记录

        对于MySQL最简单的衡量查询开销的三个指标:响应时间、扫描的行数、返回的行数。这三个指标中没有那个能完美的衡量查询的开销。
        响应时间
        响应时间只是一个表面的值。它分为两部分:服务时间、排队时间。服务时间是指数据库处理这个查询真正花费的时间。排队时间是指服务器因为等待某些资源而没有真正执行查询的时间(等待I/O操作,等待行锁...)。
        扫描的行数和返回的行数
        扫描的行数对返回的行数的比率通常很小,一般在1:1和10:1之间。理想情况下扫描行数和返回的行数应该是相同的,但一般扫描行会大于返回的行。比如做关联查询时,服务器必须要扫描多行才能生成结果集中的一行。
        扫描的行数和访问类型
        MySQL有好几种访问方式可以查询并返回一行结果。有些访问方式可能需要扫描很多行才能返回一行,也有些访问方式无需扫描就能返回结果。
        在explain中的type列就是访问类型。访问类型有:全表扫描、索引扫描、范围扫描、唯一索引扫描等。这些类型的速度从慢到快,扫描的行数从小到大。
        如果查询没有找到合适的访问类型,那么一般就是增加一个合适索引。

        

二、重构查询

1、一个复杂查询还是多个简单查询

        MySQL从设计上让链接和断开都很轻量级,在返回一个小的查询结果方面很高效。可以根据实际情况将一个复杂的查询分为几个小的查询。

2、切分查询

        对于大查询(数据量大),可以将其切分为小查询。每个查询只查询大结果的一小部分。
        例子:删除数据,可以一年删一次,也可以一个月删一次。但是一年的数据量相较于一个月的数据量是非常庞大的,一次执行可能会占满系统资源,影响其他功能。对于每月运行的查询就没有那么大的影响,而且也可以让这一次性的压力再次分散开,使得对服务器的影响再次降低。

3、分解关联查询

        对于关联查询,可以对每一个表进行一次单表查询,然后将结果集在应用程序中关联。
        分解查询的优势:

  • 让缓存的效率更高。许多应用程序可以方便的缓存单表查询对应的结果对象。
  • 将查询分解后,执行单个查询可以减少锁的竞争
  • 在应用层做关联,可以更容易对数据进行拆分,更容易做到高性能、可扩展
  • 查询效率也可能会有所提升
  • 可以减少冗余记录的查询

        

三、查询执行基础

        

        1、客户端发送一条查询给服务器
        2、服务器先检查查询缓存,如果命中缓存,则直接返回存储在缓存中的结果。否则进入下一
              阶段。
        3、服务器端进行SQL解析、预处理,再由优化器生成对应的执行计划。
        4、MySQL根据优化器生成执行计划,调用存储引擎的API执行查询。
        5、将结果返回给客户端。

1、查询状态

        对于一个MySQL连接,任何时刻都有一个状态。该状态表示了MySQL当前在做什么。可以使用show full processlist命令来查询当前状态。
        状态解释:
                sleep:线程正在等待客户端发送新的请求。
                query:线程正在执行查询或正在将结果返回给客户端。
                locked:在服务层,该线程正在等待表锁。
                analyzing and statistics:线程正在收集存储引擎的统计信息,并生成查询的执行计划。
                copying to tmp table:线程正在执行查询,并且将其结果集都复制到一个临时表中。
                sorting result:线程正在对结果集进行排序。
                sending data:这表示多种情况:线程可能在多个状态之间传送数据,或者在生成结果
                        集,或者在向客户端返回数据。

 2、查询优化处理

        MySQL会将SQL转换成一个执行计划,再按照这个执行计划和存储引擎进行交互。这个包括多个子阶段:解析SQL、预处理、优化SQL执行计划。

 语法解析和预处理
        
MySQL通过关键字将SQL语句进行解析,并生成一棵对应的”解析树“。MySQL解析器将使用MySQL语法规则验证和解析查询。
        预处理器则根据一些MySQL规则进一步检查解析树是否合法,例如检查表和数据列是否存在,解析名字和别名是否有歧义。

查询优化器
        一条查询可以有很多种执行方式,最后都返回相同的结果。优化器的作用就是找到其中最好的执行计划。
        MySQL使用基于成本的优化器,他将尝试预测一个查询使用某种执行计划时的成本,并选择其中成本最小的一个。在执行查询语句后,可以使用show status like ”last_query_cost“来查看计算成本。得出的值是根据一些信息计算的出来的:每个表或索引的页面个数、索引基数、索引和数据行长度、索引分布情况。

        

四、查询优化器的局限性

1、关联子查询

        MySQL子查询的实现非常糟糕。MySQL对IN()列表中的选项有专门的优化策略,一般会认为MySQL会执行in里面的子查询,但MySQL不是这样做的。MySQL会将相关的外层表压到子查询中。

select name

from user

where id in (select id from part where user_name="abc")

上述语句在MySQL优化后会转化成下列方式

select name

from user

where exists (select * from part where user_name="abc" and user.id=part.id)

       子查询需要根据id来关联外部表part,因为需要id字段,所以MySQL认为无法先执行这个子查询。
        优化方式一:使用inner join进行关联查询
        优化方式二:直接使用优化后的SQL形式。使用exists。

2、UNION的限制

        有时MySQL无法将限制条件从外层“下推”到内层,这使得原本能够限制部分返回结果的条件无法应用到内层查询的优化上。
        例子:如果想UNION个子句能够根据LIMIT只取部分结果集,或者希望能够先排序在合并结果集,就需要在各子句中提前分页。

(select id,name from user order by name limit 0,10)
union

(select id,name from other_user order by name limit 0,10)

order by name 

limit 0,10    

3、在同一个表上查询和更新

        MySQL不允许对同一张表同时进行查询和更新。为了绕过这一限制见下列例子。

update user

set name = (select name from user where id=1)

修改后

update user

left join(select type,name from user where id=1) a using (type)

set user.name=a.name

五、优化特定类型的查询

1、优化count()查询

        count函数的作用:可以统计某个列值的数量;可以统计行数。统计列值时不会计算NULL值。统计行数时他会忽略列直接统计所有的行数。
        对于MyISAM的count速度非常快,但有个前提不能再where条件,因为这样无须实际计算表的行数。
        对于大量的数据,count需要访问大量数据才能获取精确数据,所以可以使用汇总表统计数据。

2、优化关联查询

        确保on或者using子句的列上有索引。在创建索引时候就要考虑关联顺序。当A和B用列C关联的时候,如果优化器关联的顺序是B、A,那就不需要再B表上建立索引。一般情况,只需要在关联顺序中的第二个表的相对应列上建立索引。(这么做的原因:加速关联操作、减少索引存储空间。第二张表作为被驱动表,可以使用索引快速定位对应数据,而且建立索引使用的存储空间没有驱动表中使用的空间大)
        在group by和order by中的列尽量使用一个表中的列。这样MySQL才可能使用索引去优化。

3、优化LIMIT分页

        尽可能使用索引覆盖扫描
        使用“延时关联”,先查询带有索引的列,得出结果在去关联主表查询其他需要字段。

select id,name,age from user order by name limit 100,10

转换后

select id,name,age from user

inner join (select id from user order by name limit 100,10) a using (id)       

        使用id过滤查询的数据       

        对于顺序id,在分页时可以在条件上加上id。比如返回了上一页最后一个id为10000,然后一页数据为20条,可以使用下列方式进行查询后一页的数据。

select id,name from user where id>10000 order by id limit  20

4、优化UNION查询

        可以将where、limit、order by等子句放到子查询中,便于优化器充分利用这些条件进行优化
        除非确实需要去重操作,否则一定使用UNION ALL。如果没有ALL关键字,MySQL会给临时表加上DISTINCT,这会导致整个临时表做数据唯一性检查。         

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

element ui + echarts点击表格显示对应的图形

一、vue封装饼图、树状图、雷达图等组件 目录 resize.js需要utils.js utils.js import { parseTime } from ./yunhis/*** 表格时间格式化*/ export function formatDate(cellValue) {if (cellValue null || cellValue "") return "";var date new Da…

文心生物计算大模型重磅升级,构象预测准确度全面提升!

文心生物计算大模型家族又迎来了重磅的升级:蛋白质-小分子对接构象预测模型HelixDock,以及蛋白-蛋白复合物结构预测模型HelixFold-Multimer准确度全面提升。这两项新技术可以大幅提升蛋白质-小分子的对接构象及蛋白-蛋白复合物结构预测的精度&#xff0c…

2023年亚太杯APMCM数学建模大赛数据分析题MySQL的使用

2023年亚太杯APMCM数学建模大赛 以2022年C题全球变暖数据为例 数据分析: 以2022年亚太杯数学建模C题为例,首先在navicat建数据库然后右键“表”,单击“导入向导”,选择对应的数据格式及字符集进行数据导入 导入之后&#xff0c…

外贸客户管理系统是什么?推荐的管理软件?

外贸客户管理系统哪个好用?海洋建站如何选管理系统? 外贸客户管理系统,是一款专为外贸企业设计的客户关系管理系统,旨在帮助外贸企业建立与维护客户关系,提高客户满意度和忠诚度,提升企业业绩。海洋建站将…

005.终端信息、日期、调试

编写命令行shell脚本时,总是免不了处理当前终端的相关信息,比如行数、列数、光标位置、遮盖的密码字段等。tput和stty是两款终端处理工具。 1、获取终端信息 a. tput 命令 获取终端行数 tput cols 获取终端列数 tput lines 打印当前的终端名 tput…

java创造对象

java创造对象主要分为以下几个步骤 获取对应的类,查看是否加载,如果没有加载把类进行加载根据类的信息可以直接获取到实例的大小,分配对应内存调用实例的方法 比如说 class bb implements Serializable {private String bb; }class aa ext…

【C#学习】给FormClosing增加消息响应函数

第一步:增加消息句柄 第二步:编写消息函数 private void Form1_FormClosing(object sender, FormClosingEventArgs e) {//add your code hereserialPort1.Close();}

【23真题】懒得出题!连续两年试卷相同!

连续两年出题一样,老师都懒得出题的院校又被我抓到一所!(上次是天津工业22和21年一模一样),这次沈阳工业的老师多多少少改了几个数,但是也大差不差,考这所院校,猛刷真题,…

亚马逊鲲鹏系统可全自动化批量操作亚马逊买家号

亚马逊鲲鹏系统可以注册买家号、智能养号、自动下单、自动留评、QA等,是一款从注册到下单于一体的软件。 如果想要自动化注册,那么准备好账号所需要的邮箱、ip、手机号之后就可以进行自动注册了,注册时可以自动输入账号密码信息、自动接收验证…

11.3SpringMVC

一.概念 1.SpringMvc: a.构建在Servlet(api)基础上. b.是一个Web框架(HTTP). c.来自于Spring webMVC模块. 2.MVC 二.注册路由的注解 1.RequestMapping("/test") // 路由注册 注意: 这个注解在类和方法上都要使用,代表不同等级的路由. 2.RestController a)R…

ALPC_Natural_Selection

刚刚结束的ICPC2023沈阳是自然选择号的最后一场 XCPC 区域赛,很高兴也很幸运能拿到校排名 rk4,圆了一个这半年才开始做的梦。在这里讲一下这支队伍的故事。 组队、训练 本来和wjy666(aka maple)打完 EC Final 之后是想要退役的&…

“程序员们的奔溃瞬间”——分享你最令你哭笑不得的程序员经历

文章目录 每日一句正能量前言编程趣事后记 每日一句正能量 每件事最后都会是好事。如果不是好事,说明还没到最后。 前言 作为程序员,我们时常会遇到各种奇怪的错误和挑战,有时候我们会崩溃,但更多的时候,我们会从中学…

从0开始学习JavaScript--JavaScript基础

JavaScript作为一门前端编程语言,在现代web开发中扮演着不可替代的角色。它不仅为网页增添了动态和交互性,而且随着Node.js的崛起,也在服务器端开发中占据了重要地位。在本章节中,我们将探讨JavaScript的作用、重要性以及与其他前…

第二证券:大爆发!道指一夜大涨近500点

当地时间11月14日,美股三大股指显着上涨,其间,道指涨1.43%,标普500指数涨1.91%,纳斯达克指数涨2.37%。 标普500指数创4月份以来的最大单日涨幅。美债收益率大跌。美国10月CPI数据进步了美联储结束加息行为的希望&…

Find My平衡车|苹果Find My技术与平衡车结合,智能防丢,全球定位

随着人们环保意识的加强,电动车的数量与日俱增。与此同时,科学家经过潜心的研究,终于开发出新款两轮电动平衡车。两轮电动平衡车是一种新型的交通工具,它与电动自行车和摩托车车轮前后排列方式不同,而是采用两轮并排固…

舞台演出控制软件:QLab Pro

QLab Pro是一款功能强大的现场多媒体控制器软件,专为Mac用户设计。它提供了一个直观简洁的用户界面,使得用户能轻松管理和组织所有的媒体资源。QLab Pro支持导入各种音频和视频文件,并具备强大的音频、视频处理和灯光控制功能,可以…

Umi-OCR :一个完全离线的OCR图片转文字识别软件。

Umi-OCR :一个完全离线的OCR图片转文字识别软件。 开源免费,支持截屏或批量导入图片,并能识别多国语言,合并段落,处理竖排文字。 排除图片中的水印区域,提取干净的文本。 忽略特定区域的文字识别&#x…

什么是Vue.js中的单向数据流(one-way data flow)?为什么它重要?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

colormap与colorbar应用

一,colormap 常见色度枚举值如下 应用如下 img cv2.applyColorMap(img, cv2.COLORMAP_JET) cv2.imshow(img,img) cv2.waitKey(0) cv2.destroyAllWindows() 常用的COLORMAP_JET效果如下,该模式常用于生成热力图 二,colorbar colorbar所有…

洗袜子的洗衣机哪款好?家用小洗衣机推荐

最近这两年在洗衣机中火出圈的内衣洗衣机,它不仅可以清洁我们较难清洗的衣物,自带除菌功能,可以让衣物上的细菌,还能在清洗的过程中呵护我们衣物的面料,虽然说它是内衣洗衣机,它的功能不止可以清洗内衣&…
最新文章