当希望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查询执行的基础的更多相关文章

  1. MySQL查询执行的基础——查询优化处理

    查询的生命周期的下一步是将一个SQL转换成一个可执行计划,MySQL再按照这个计划和存储引擎进行交互 语法解析器和预处理 首先,MySQL通过关键词将SQL语句进行解析,并生成一颗对应的"解 ...

  2. MySQL查询执行过程

    MySQL查询执行路径 1. 客户端发送一条查询给服务器: 2. 服务器先会检查查询缓存,如果命中了缓存,则立即返回存储在缓存中的结果.否则进入下一阶段: 3. 服务器端进行SQL解析.预处理,再由优 ...

  3. mysql 查询执行的流程

    1.客户端发送一个请求给服务器.2.服务器先检查查询缓存,命中了缓存,直接返回缓存中的数据,否则进入下一个阶段.3.服务器进行sql解析,预处理,再由优化器生成对应的执行计划.4.mysql根据执行计 ...

  4. MySQL查询执行路径

    1.客户端发送一条查询给服务器2.服务器先检查查询缓存,如果命中缓存,则立刻返回存储在缓存中的结果.3.服务器端进行SQL解析.预处理,再由优化器生成对应的执行计划.4.MySQL根据优化器生成的执行 ...

  5. 使用explain查看mysql查询执行计划

    explain语句: 字段解释: type:     all(全表扫描)     ref() possible_keys:     预测使用什么列做为索引 key:     实际使用的key     ...

  6. MySQL优化技巧之五(mysql查询性能优化)

    对于高性能数据库操作,只靠设计最优的库表结构.建立最好的索引是不够的,还需要合理的设计查询.如果查询写得很糟糕,即使库表结构再合理.索引再合适,也无法实现高性能.查询优化.索引优化.库表结构优化需要齐 ...

  7. MySQL查询性能优化(精)

    MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...

  8. 170727、MySQL查询性能优化

    MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...

  9. 《高性能MySQL》之MySQL查询性能优化

    为什么查询会慢? 响应时间过长.如果把查询看做是一个任务,那么它由一系列子任务组成,每个子任务都会消耗一定的时间.如果要优化查询,实际上优化其子任务,要么消除其中一些子任务,要么减少子任务的执行次数, ...

随机推荐

  1. 《FPGA零基础入门到精通视频教程》-第001a讲软件的安装

    高清视频和配套讲义这里下载 http://www.fpgaw.com/thread-67758-1-1.html 优酷视频不是很清晰

  2. 14.2 InnoDB and the ACID Model

    14.2 InnoDB and the ACID Model ACID 模型是一组数据库设计原则,强调可靠性方面对于商业数据和关键人物. MySQL 包含组件比如InnoDB存储引擎坚持ACID 模型 ...

  3. POJ 2774 最长公共子串

    一定好好学SAM...模板在此: #include<iostream> #include<cstdio> #include<cmath> #include<a ...

  4. 设计模式(二): BUILDER生成器模式 -- 创建型模式

    1.定义 将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式. 2.适用场景 1. 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式 ...

  5. Bloom Filter(布隆过滤器)

    布隆过滤器用于测试某一元素是否存在于给定的集合中,是一种空间利用率很高的随机数据结构(probabilistic data structure),存在一定的误识别率(false positive),即 ...

  6. 在Excel中将数字设置成文本格式的技巧

    在Excel中将数字设置成文本格式的技巧 一个简单的方法,利用[数据]菜单的[分列]功能来将数字设置为文本格式.具体操作步骤为: 1.选中所有需要处理的数字单元格. 2.选择[数据]菜单[分列]功能. ...

  7. oracle事务和锁

    数据库事务概括 1. 说明 一组SQL,一个逻辑工作单位,执行时整体修改或者整体回退. 2.事务相关概念 1)事务的提交和回滚:COMMIT/ROLLBACK 2)事务的开始和结束 开始事务:连接到数 ...

  8. Oracle分页查询与RowNum

    1. RowNum伪列 Oracle中,RowNum是一个伪列,表示当前记录是查询结果集中的第几条. RowNum在使用上应该注意,不能在where条件中用RowNum大于.大于等于.等于某个大于1的 ...

  9. 【Python排序搜索基本算法】之Dijkstra算法

    Dijkstra算法和前一篇的Prim算法非常像,区别就在于Dijkstra算法向最短路径树(SPT)中添加顶点的时候,是按照ta与源点的距离顺序进行的.OSPF动态路由协议就是用的Dijkstra算 ...

  10. Spring 3.2 ClassMetadataReadingVisitor 错误

    nested exception is java.lang.IncompatibleClassChangeError: class org.springframework.core.type.clas ...