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 正在占用大量的时间。这通常表示,某个地方有异常了。

  

时间: 2024-10-10 02:30:55

MySQL查询执行的基础的相关文章

mysql 查询执行的流程

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

MySQL查询执行

当我们希望MySQL能够以更高的性能运行查询时,最好的办法就是弄清楚MySQL是如何优化和执行查询的.一旦理解了这一点,很多查询优化工作实际上就是遵循一些原则让优化器能够按照预想的合理方式运行 当我们想向MySQL发送了一个请求时,MySQL到底做了什么: 客户端首先发送一条查询请求给服务器 服务器首先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果,否则进入下一阶段. 服务器端进行SQL解析.预处理,再由优化器生成对应的执行计划 MySQL根据优化器生成的执行计划,调用存储引擎的AP

图说mysql查询执行流程

1. 查询缓存,判断sql语句是否完全匹配,再判断是否有权限,两个判断为假则到解析器解析语句,为真则提取数据结果返回给用户. 2. 解析器解析.解析器先词法分析,语法分析,检查错误比如引号有没闭合等,然后生成解析树. 3. 预处理.预处理解决解析器无法决解的语义,如检查表和列是否存在,别名是否有错,生成新的解析树. 4. 优化器做大量的优化操作. 5. 生成执行计划. 6. 查询执行引擎,负责调度引擎获取相应数据 7. 返回结果.

MySQL查询执行路径

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

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

explain语句: 字段解释: type: all(全表扫描) ref() possible_keys: 预测使用什么列做为索引 key: 实际使用的key ref: 参考,引用 rows: 扫描的行数 id: 扫描的行数 extra: 使用什么来定位

170727、MySQL查询性能优化

MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下我们从数据库的索引和查询语句的设计两个角度介绍如何提高MySQL查询性能. 数据库索引 索引是存储引擎中用于快速找到记录的一种数据结构.索引有多种分类方式,按照存储方式可以分为:聚簇索引和非聚簇索引:按照数据的唯一性可以分为:唯一索引和非唯一索引:按照列个数可以分为:单列索引和多列索引等.索引也有多

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

为什么查询会慢? 响应时间过长.如果把查询看做是一个任务,那么它由一系列子任务组成,每个子任务都会消耗一定的时间.如果要优化查询,实际上优化其子任务,要么消除其中一些子任务,要么减少子任务的执行次数,要么让子任务运行得更快. 查询的生命周期: 客户端->服务器->服务器上解析->生成执行计划->执行->返回结果给客户端. 其中”执行”包括大量为了检索数据到存储引擎的调用以及调用后的数据处理,包括排序.分组等. 慢查询:优化数据访问 查询性能低下最基本的原因:访问的数据太多.

SQL查询执行过程

MYSQL查询执行过程 客户端向服务器发送请求 服务器查询缓存,缓存中命中则结束,将结果返回客户端(返回前会检查用户权限),否则继续下边步骤 服务器端进行SQL解析.预处理,再由优化器生成对应的执行计划 根据执行计划调用存储引擎的API执行查询 将结果返回客户端 一.查询缓存 如果一条SQL语句以select开头,MySQL服务器将会尝试先在缓存中查询.每个cache都是以SQL文本做为key的,所以如果SQL语句中大小写不同也无法命中. 设置:my.cnf(Linuxe)/my.ini(Win

MySQL 查询缓存

MySQL查询执行流程 查询流程: 客户端发送一条查询给服务器: 服务器先检查查询缓存,如果命中了缓存,则立即返回存储在缓存中的结果:否则,进入下一阶段: 服务器进行SQL解析.预处理,再由优化器生成对应的执行计划: MySQL根据优化器生成的执行计划,调用存储引擎的API来执行查询: 将结果返回给客户端: 查询缓存 用于保存MySQL查询语句返回的完整结果,被命中时,MySQL会立即返回结果,省去解析.优化和执行等阶段: MySQL保存结果于缓存中,把select语句本身做hash计算,计算的