一图解析MySQL执行查询全流程
摘要:当我们希望MySQL能够以更高的性能运行查询时,最好的办法就是弄清楚MySQL是如何优化和执行查询的。
本文分享自华为云社区《mysql执行查询全流程解析》,作者:breakDraw。
mysql执行查询的过程

- 客户端先发送查询语句给服务器
- 服务器检查缓存,如果存在则返回
- 进行sql解析,生成解析树,再预处理,生成第二个解析树,最后再经过优化器,生成真正的执行计划
- 根据执行计划,调用存储引擎的API来执行查询
- 将结果返回给客户端。
一、客户端到服务端之间的原理
- 客户端和服务端之间是半双工的, 即一个通道内只能一个在发一个接收, 不能同时互相发互相接收
- 客户端只会发送一个数据包给服务端,并不会在应用层拆成2个数据包去发(max_allowed_packet可以设置数据包最大长), 这关系到sql语句不能太长。
- 服务端返回给客户端可以有多个数据包, 但是客户端必须完整接收,不能接到一半停掉连接或用连接去做其他事(UI界面可以操作,不同的线程)
- 例如java,如果没设置fetchSize,那么都是一次性把结果读进内存。当你使用resultSet的时候,其实已经全部进来了,而不是一条条从服务端获取。————使用fetch Size边读边处理的坏处: 服务端占用的资源时间变久了。
查询mysql服务此时的状态
使用 show full processlist 命令可以查看mysql服务端某些线程的状态
- Sleep 正在等待客户端发送新的请求
- Query 正在执行查询, 或者发结果发给客户端
- Locked 正在等待表锁(注意表锁是服务器层的, 而行锁是存储引擎层的,行锁时状态为query)
- Analyzing and statistics 正在生成查询的计划或者收集统计信息
- copying to tmp table 临时表操作,一般是正在做group by等操作
- sorting result 正在对结果集做排序
- sending data 正在服务器线程之间传数据
二、查询缓存
- 缓存的查询在sql解析之前进行。
- 缓存的查找通过一个 对大小写敏感的哈希表实现,即直接比对sql字符串。
- 因此只要有一个字节不同,都不会匹配中。(毕竟还没开始解析,大小写什么的他也不知道要不要区分)
- 第7章中有更详细的查询缓存。
三、查询优化处理
1.语法解析器和预处理
- 这里就是把sql做解析, 变成一个解析树。解析时会做mysql语法规则验证。
- 语法解析器: 检查关键字错误、关键字顺序、引号匹配
- 预处理:和元数据关联校验, 检查数据表和列是否存在,解析名字和别名。
- 权限校验
2.查询优化器(重点)
- mysql可能会生成多种计划, 他会分别计算一个预测成本值,然后选一个成本最小的计划
- 计算信息来自于 表的页面个数、索引分布、长度、个数、数据行长度
- 因为多种原因,可能不会选择到最优的计划,有偏差
- 静态优化和动态优化的区别:
静态优化类似“编译期优化”,只和语句结构有关,和具体值无关
动态优化是在运行中去优化的,需要依赖索引行数、where取值,执行次数可能比静态优化要多。
mysql的优化类型
- 关联表(join)的顺序可能会变
- outer join可能会变成内连接
- 优化条件表达式, 例如 5=5 AND a>5被简化成a>5
- 优化MAX\MIN, 如果是MAX(索引),那么直接拿B+树的第一条或者最后一条即可。
- 当发现某个查询或者表达式的结果是可以提前计算出来的时候,就会优化成常数
- 索引覆盖,如果只要返回索引列,就不会走到最底层去。
- 子查询优化
- 提前终止查询(例如LIMIT)
- 等值传播: join中可能把左表的where 拿给右表一起用
- IN(1,2,3,4,5,6)这个条件, 并不是简单遍历判断, 会先排序,然后用二分去判断是否存在。
3.数据和索引的统计信息
- 统计信息是存储引擎去计算的,不同的存储引擎有不同的统计信息
- 服务器层生成查询计划时,会向存储引擎获取这些信息。
4.MYSQL对关联查询的执行
- join查询的本质其实是读取临时表做关联
- 例如a inner join b on a.id=b.id where a.xx=y
- 遍历a的每一行(此时a表本质上是 select * from a where a.xx=y)
- 在那行中a的id被定下来, 那么就会去获取一个临时表,临时表为(select * from b where a.id = id)
- 接着用这个临时表和a那一行拼接,输出多行。
- 然后再用这里的结果作为临时表,给更上层的关联去用(嵌套查询的含义)。
- 如果是left join,则就是临时表如果为空,则给a那一行拼接一个null。
5. 执行计划中的join树

6. 关联查询优化器
- join实际执行的顺序会关系到性能
- 例如a\b\c三个表关联, 可能先让a和b关联得到的临时表里的记录只有10条, 而如果让a和c先关联,会有10000条, 那么后面的效率就会截然不同
- EXPLAIN EXTENDED可以展示关联的顺序
- STRAIGHT_JOIN可以手动指定关联顺序
- mysql自己会评估搜索一个最优的顺序, 但如果join表太多,则无法搜完所有结果(O(n!)), 那时候就会采用贪心。 是否使用贪心算法的边界值可以根据optimizer_seartch_depth去指定。
7.排序优化
- 如果排序的量小,就用内存快速排序;如果排序的量大,就用文件排序
- mysql有2种取排序数据的方式:
- 两次传输排序: 先取要排序的字段加行序号,按照字段排序好之后,再根据行索引一条条取读
优点: 排序时占用内存小。
缺点: 排序之后读的过程会很慢,根据行序号取读不是很方便 - 单次传输排序: 直接把行读出来(行里只有需要用的列,不一定是整行) ,然后排序
优点: 把全部行读出来相当于顺序IO,读取速度快
缺点: 可能会很大导致需要文件排序
- 关联查询order by的注意事项
如果order by的列 都 来自关联的 第一张 表,则直接第一张表join的时候就排序了。
除此之外!! 都是全部join完,再排序! 就算用了limit,也是全部join+排序后, 再limit的!
四、查询执行计划
- 执行计划是一个数据结构
五、返回结果给客户端
- 用tcp封包并逐步传送,而不是全部准备好再发送。
一图解析MySQL执行查询全流程的更多相关文章
- 一张图轻松掌握 Flink on YARN 应用启动全流程(上)
Flink 支持 Standalone 独立部署和 YARN.Kubernetes.Mesos 等集群部署模式,其中 YARN 集群部署模式在国内的应用越来越广泛.Flink 社区将推出 Flink ...
- 详细图解 Netty Reactor 启动全流程 | 万字长文 | 多图预警
本系列Netty源码解析文章基于 4.1.56.Final版本 大家第一眼看到这幅流程图,是不是脑瓜子嗡嗡的呢? 大家先不要惊慌,问题不大,本文笔者的目的就是要让大家清晰的理解这幅流程图,从而深刻的理 ...
- 程序员收藏必看系列:深度解析MySQL优化(二)
程序员收藏必看系列:深度解析MySQL优化(一) 性能优化建议 下面会从3个不同方面给出一些优化建议.但请等等,还有一句忠告要先送给你:不要听信你看到的关于优化的“绝对真理”,包括本文所讨论的内容,而 ...
- 【拖拽可视化大屏】全流程讲解用python的pyecharts库实现拖拽可视化大屏的背后原理,简单粗暴!
"整篇文章较长,干货很多!建议收藏后,分章节阅读." 一.设计方案 整体设计方案思维导图: 整篇文章,也将按照这个结构来讲解. 若有重点关注部分,可点击章节目录直接跳转! 二.项目 ...
- 【爬虫+数据分析+数据可视化】python数据分析全流程《2021胡润百富榜》榜单数据!
目录 一.爬虫 1.1 爬取目标 1.2 分析页面 1.3 爬虫代码 1.4 结果数据 二.数据分析 2.1 导入库 2.2 数据概况 2.3 可视化分析 2.3.1 财富分布 2.3.2 年龄分布 ...
- canvas 制作flappy bird(像素小鸟)全流程
flappy bird制作全流程: 一.前言 像素小鸟这个简单的游戏于2014年在网络上爆红,游戏上线一段时间内appleStore上的下载量一度达到5000万次,风靡一时, 近年来移动web的普及为 ...
- 全球首个全流程跨平台界面开发套件,PowerUI分析
一. 首个全流程跨平台界面开发套件,PowerUI正式发布 UIPower在DirectUI的基础上,自主研发全球首个全流程跨平台界面开发套件PowerUI(PUI)正式发布,PowerU ...
- CentOS7+CDH5.14.0安装全流程记录,图文详解全程实测-总目录
CentOS7+CDH5.14.0安装全流程记录,图文详解全程实测-总目录: 0.Windows 10本机下载Xshell,以方便往Linux主机上上传大文件 1.CentOS7+CDH5.14.0安 ...
- Mysql漂流系列(一):MySQL的执行流程
MySQL的执行流程 MySQL的执行流程: MySQL的执行流程分析: 1.当我们请求mysql服务器的时候,MySQL前端会有一个监听,请求到了之后,服务器得到相关的SQL语句,执行之前(虚线部分 ...
- FFmpeg编解码处理1-转码全流程简介
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10584901.html FFmpeg编解码处理系列笔记: [0]. FFmpeg时间戳详 ...
随机推荐
- YXの每日挂分记录
7.11 T1 不开两倍数组 100->60. 7.18 T2 dp+矩乘 转移不判边界 100->10. 7.20 T2 人类智慧 1e6 n log n 100->10,求前 5 ...
- 针对Jupter Kernel error的问题解决
首先打开Anaconda Prompt 输入jupyter kernelspec list查看安装的内核和位置 到显示的的目录下面找到 kernel.josn这个文件 修改为现在的python环境路径 ...
- c#中适配器模式详解
基础介绍: 想象这样一个场景,原项目中接口返回的数据是XML格式的数据,但现在来了一个新客户,它期望接口返回的数据类型为json格式的. 想要实现要么就是改原有接口,但这样就违反了开闭原则,容 ...
- [Python急救站课程]简单的人机对话
一个简单的人机对话程序 name = input("输入姓名:") # input输入数据 print("{}同学,学好Python,前途无量!".format ...
- ReverseMe-120
一道好题,没解出来但是收获很多 贴两位大牛的题解 [精选]攻防世界逆向高手题之ReverseMe-120-CSDN博客 攻防世界ReverseMe-120详解_攻防世界reverseme基本思路-CS ...
- 信创就用国产的 Solon Java Framework,v2.6.0 发布
先吹牛! 在 v2.6 这个新的里程碑节点,Solon 又完成了几件惊天大事(每一件,都是经历了漫长时间打磨与积累): (1)Solon Native,有了第一个开源案例:dromara/neutri ...
- SpringBoot + 通义千问 + 自定义React组件,支持EventStream数据解析!
一.前言 大家好!我是sum墨,一个一线的底层码农,平时喜欢研究和思考一些技术相关的问题并整理成文,限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教. 最近ChatGPT非常受欢迎,尤其是在编 ...
- [UOJ216][UNR#2 2A] Jakarta Skyscrapers
印尼首都雅加达市有 $10^{18}$ 座摩天楼,它们排列成一条直线,我们从左到右依次将它们编号为 $1$ 到 $10^{18}$ .除了这 $10^{18}$ 座摩天楼外,雅加达市没有其他摩天楼. ...
- 【Linux API 揭秘】container_of函数详解
[Linux API 揭秘]container_of函数详解 Linux Version:6.6 Author:Donge Github:linux-api-insides 1.container_o ...
- 决策树(ID3、C4.5、CART算法numpy实现)
什么是决策树? 决策树(decision tree)是一个树结构(可以是二叉树或非二叉树). 其每个非叶节点表示一个特征属性上的测试,每个分支代表这个特征属性在某个值域上的输出,而每个叶节点存放一个类 ...