MySQL查询执行的基础
当希望MySQL能够以更高的性能运行查询时,最好的办法就是弄清楚MySQL是如何优化和执行查询的。一旦理解这一点,很多查询优化实际上就是遵循一些原则让优化器能够按照预想的合理的方式运行。
换句话说,是时候回头看看我们之前讨论的内容了:MySQL执行一个查询的过程。当向MySQL发送一个请求的时候,MySQL到底做了什么。
1 客户端发送一条查询给服务器。
2 服务器首先检查缓存,如果命中缓存,则立即返回存储在缓存的结果,否则进入下一阶段。
3 服务器进行sql解析,预处理,再由优化生成器生成对应的执行计划。
4 MySQL根据优化器生成的执行计划,调用存储引擎的api来执行查询。
5 强结果返回给客户端。
上面的每一步都比想象的负载,我们在后续章节中将继续讨论。我们会看到在每一个阶段查询出来处于何种状态。查询优化器是其中特别复杂也是特别难理解的部分。还有很多例外的情况,例如,当查询使用绑定变量之后,执行路径会有所不同,我们将在下一章讨论这一点。
一 MySQL客户端/服务器通信协议
一般来说,不需要去理解MySQL通信协议的内部实现细节,只需要大致理解通信协议是如何工作的。MySQL客户端和服务器之间的通信协议是“半双工 ”的,这意味着,在任何一个时刻,要么是由服务器向客户端发送数据,要么是由客户端向服务器发送数据,这两个动作不能同时发生。所以,我们无法也无须将一个消息切成小块来独立发送。
这种协议让MySQL通信简单快速,但是也从很多地方限制住了MySQL。一个明显的限制是,这意味着无法进行流量控制。一旦一端开始发生消息,另一端要接收完整个消息才能响应它。这就像来回的抛球游戏:任何时刻只有一个人能控制球,而且只有控制球的一方才能将球抛回去(发送消息)。
客户端用一个单独的数据包将查询传给服务器。这也是为什么当查询的语句很长的时候参数max_allowed_packet 就特别重要了。一旦客户端发送了请求,它能做的事情,就只是等待结果了。
相反的,一般服务器响应给客户的数据通常很多,由多个数据包组成。当服务器开始响应客户端请求时,客户端必须完整的接受整个返回结果,而不能简单的只取前面几条结果,然后然服务器停止发送数据,这种情况下,客户端若接收完整的结果,然后取前面几条需要的结果,或者接收完几条结果后,就粗暴的断开连接,都不是好主意。这也是在必要的时候一定要在查询语句中加上limit限制的原因。
换一种方式解释这种行为:当客户端从服务器取数据时,看起来是一个数据拉去的过程,但实际上是MySQL在向客户端推送数据的过程。客户端不断的接收从服务器推送的数据,,客户端也无法让服务器停下来。
多数连接MySQL的库函数都可以获得全部结果集并缓存到内存里,还可以逐行获取需要的数据。默认一般是获得全部结果集并缓存到内存中。MySQL通常需要等待所有的数据都已经发送给客户端,才能释放这条查询所占的资源,所有接受全部结果通常可以减少服务器压力,让查询能够早点结束,早点释放相应的资源。
当使用多数连接MySQL的库函数从MySQL获取数据时,其结果看起来都像是从MySQL服务器获取的数据,而实际上都是从这个库函数的缓冲读取数据。多数情况下这没什么问题,但是如果需要返回一个很大的结果集的时候,这样走并不好,因为库函数会花费很多时间和内存来存储所有的结果集。如果能尽早的开始处理这些结果集,就能大大减少内存的消耗,这种情况下可以不使用缓存记录结果而是直接处理。这样走的缺点是,对于服务器来说,需要查询完成后才能释放资源,所以在和客户端交互的整个过程中,服务器的资源都是被这个查询所占用的。
查询状态
对于一个MySQL的连接,或者说是一个线程,任何时刻都有一个状态,该状态表示了MySQL当前正在做什么。有很多种方式能查看当前的状态,最贱的的是使用SHOW FULL PROCESSLIST 命令(该命令返回结果中的Command列就表示当前的状态)。在一个查询的生命周期中,转台会变回很多次。MySQL官方收藏对这些状态值的含义有最权威的解释,下面将这些状态列出来,并做一个简单的解释。
Sleep
线程正在等待客户端发送新的请求
Query
线程正在执行查询或者正在将结果发送给客户端。
Locked
在MySQL服务器层,该线程正在等待表锁。在存储引擎实现的锁,例如Innodb的行锁,并不会体现在该线程状态中。对于myisam来说这是一个比较典型的状态,但在其他没有行锁的引擎中也会长出现。
Analyzing and statistics
线程正在收集存储引擎的统计信息,并生成查询的执行计划。
Copying to tmp table【on disk】
线程正在执行查询,并且将其结果集都复制到一个临时表中,这种状态一般要么是做Group by 操作,要么是文件排序操作,或者是UNION 操作。如果这个状态后面还有on disk 标记,那么表示MySQL正在将一个内存临时表放到磁盘上。
Sorting result
线程正在对结果集进行排序。
Sending data
这表示多种情况:线程可能是在多个状态之间传送数据,或者结果集,或者在向客户端返回数据。
了解这些状态的戒备含义非常有用,这可以让你更快的了解当前谁正在持球。在一个繁忙的服务器上,可能会看到大量的不正常状态,例如statistics 正在占用大量的时间。这通常表示,某个地方有异常了。
MySQL查询执行的基础的更多相关文章
- MySQL查询执行的基础——查询优化处理
查询的生命周期的下一步是将一个SQL转换成一个可执行计划,MySQL再按照这个计划和存储引擎进行交互 语法解析器和预处理 首先,MySQL通过关键词将SQL语句进行解析,并生成一颗对应的"解 ...
- MySQL查询执行过程
MySQL查询执行路径 1. 客户端发送一条查询给服务器: 2. 服务器先会检查查询缓存,如果命中了缓存,则立即返回存储在缓存中的结果.否则进入下一阶段: 3. 服务器端进行SQL解析.预处理,再由优 ...
- mysql 查询执行的流程
1.客户端发送一个请求给服务器.2.服务器先检查查询缓存,命中了缓存,直接返回缓存中的数据,否则进入下一个阶段.3.服务器进行sql解析,预处理,再由优化器生成对应的执行计划.4.mysql根据执行计 ...
- MySQL查询执行路径
1.客户端发送一条查询给服务器2.服务器先检查查询缓存,如果命中缓存,则立刻返回存储在缓存中的结果.3.服务器端进行SQL解析.预处理,再由优化器生成对应的执行计划.4.MySQL根据优化器生成的执行 ...
- 使用explain查看mysql查询执行计划
explain语句: 字段解释: type: all(全表扫描) ref() possible_keys: 预测使用什么列做为索引 key: 实际使用的key ...
- MySQL优化技巧之五(mysql查询性能优化)
对于高性能数据库操作,只靠设计最优的库表结构.建立最好的索引是不够的,还需要合理的设计查询.如果查询写得很糟糕,即使库表结构再合理.索引再合适,也无法实现高性能.查询优化.索引优化.库表结构优化需要齐 ...
- MySQL查询性能优化(精)
MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...
- 170727、MySQL查询性能优化
MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...
- 《高性能MySQL》之MySQL查询性能优化
为什么查询会慢? 响应时间过长.如果把查询看做是一个任务,那么它由一系列子任务组成,每个子任务都会消耗一定的时间.如果要优化查询,实际上优化其子任务,要么消除其中一些子任务,要么减少子任务的执行次数, ...
随机推荐
- 新发现:AirDroid(用Web端控制自己的手机发信息)
http://web.airdroid.com/ 好多功能呀,有空研究研究 http://jingyan.baidu.com/article/b24f6c82cd4ade86bfe5daf3.html ...
- 根据Hash分块存储文件
迷你云默认存储方式是Hash存储模式,文件内容存储在本地硬盘,而非明文存储模式 一.下图大致说明了情况 <ignore_js_op> 二.工作原理 1.假设用户上传了A.doc文件,迷你云 ...
- (step5.1.2)hdu 2473(Junk-Mail Filter——并查集)
题目大意:输入两个整数n,m(n表示点的个数,m表示操作数).在接下来的m行中,对点的操作有两种 1)M a b . 表示将a.b并到一个集合中 2)S a .表示将a从原来的集合中去除,而成为一个单 ...
- Hyper-V连接虚拟机异常,“无法进行连接,因为可能无法将凭据发送到远程计算机”
前两天把公司的TFS从2010升级到TFS2012(昨天又升级到TFS2013).今天使用服务器Hyper-V连接虚拟机时居然报错了. 翻看各种日志,虽然错误大一对一对地,但找不到任何有用的信息.无奈 ...
- Java学习日记-2.5 关于0和无穷
1. 无穷 Java中将无穷定义为浮点数,分为正负无穷,分别为POSITIVE_INFINITY和NEGATIVE_INFINITY 2. null null在java中可以理解为一个特殊的引用类型, ...
- linux获取CPU温度
Centos系列 1 yum install lm_sensors 2 sensors-detect 3 sensors Ubuntu系列(多了service module-init-tools st ...
- HPROF学习
抓取HPROF log 1. GUI 可以通过 adt-bundle-windows-x86_64-20140702\sdk\tools\monitor.bat来抓取. 打开软件,选中相应的包,比如“ ...
- N - Optimal Milking - POJ 2112(二分图多重匹配+Floyd+二分搜索)
题意:有K太挤奶机,C头奶牛,每个挤奶机每天只能为M头奶牛服务,下面给的K+C的矩阵,是形容相互之间的距离,求出来走最远的那头奶牛要走多远 分析:应该先使用floyd求出来点之间的最短路??(不晓得给 ...
- 用js代码判断是否IE浏览器
判断是否IE的方法: var isIE = function(ver) { var div = document.createElement("div"), status; div ...
- setTimeout中所执行函数中的this,永远指向window
注意是要延迟执行的函数中的this哦!! //片段一 setTimeout("alert(this)", 1); // [object Window] //片段二 var obj ...