一、sql查询执行过程概括

下面给出的mysql基本架构示意图,从中你可以清楚的mysql的各个模块和执行过程。

大体来说可以分为两部分Server层和储存引擎层。Server层包括连接器、查询缓存、分析器、优化器、执行器等,覆盖了mysql的大部分核心服务功能,以及所有的内置函数(如日期、时间、数字和加密函数等)

储存引擎层负责数据的储存和提取。其架构模式是插件式的,支持Innodb、MyISAM等多个储存引擎。现在最常用的储存引擎是Innodb,从Mysql5.5.5开始为其默认引擎。

从图中不难看出所有的引擎都是公用server层。不知道每个组件干什么用?先对图中的组件有一个大概印象,接下来将介绍server层的一些组件的作用。

二、连接器

我们会先要连接到数据库,这时候接待你的就是连接器,连接器负责客户端和数据库建立连接、获取权限、维持和管理连接。客户端连接的命令一般会这样写:

mysql -h$ip -u$name -p$pwd

在完成经典的tcp三次握手之后建立连接、一旦建立连接和认证通过,连接器会从权限表中查询你拥有的权限,此连接的权限都会依赖此权限(修改权限后也不会改变,除非重新启动)

连接完成后,如果没有动作,则会处于空闲状态,可以用show processlist, 下面是命令的返回结果,其中Sleep表示有一个空闲连接

当客户端太长时间没有动静,连接器就会自动断开。这个时间参数可以根据wait_timeout控制,默认是8小时。

在数据库里面,长连接是指连接成功之后,客户端有请求,则会一直用这个连接。短链接是指每一次执行很少的查询后就会断开连接,之后查询则需要重新建立连接。

建立连接的过程比较复杂,占用的时间也比较长 ,所以笔者建议最好使用长连接。

但是长连接也不是十全十美,当你建立长连接之后,你可能会发现mysql占用的内存涨的非常快,因为mysql在执行的过程中所产生的临时对象是管理在该连接对象里面的。这些资源在连接断开的时候才会释放,当长连接持续过久,可能内存占用过大,就会被系统强行杀掉,从表面上看是mysql异常重启了。

所以我们一般会怎么解决这种问题呢。我们一般会考虑下面两种方案:定期断开长连接。在使用一段时间后或者执行一次占内存较大的查询后会断开连接,之后查询再连接。

如果是mysql5.7后的版本,可以通过执行mysql_reset_connection来初始化资源,该过程不会去重新连接和验证权限

三、查询缓存

当建立连接完成后,就可以执行查询语句了,此时会执行查询逻辑的第二步:查询缓存

可以参考上图,mysql拿到一个查询后,会先到查询缓存去看看之前是否执行过此条语句。之前执行的结果会以key-value的形式被直接存在内存里面。如果语句不在缓存中,则会继续执行下面的步骤,最后将结果缓存到查询缓存中。

但是一般情况下都不会建议用查询缓存,因为一旦对一张表进行更新插入等更改表的操作,关于这个表的缓存就是被清空。由此导致查询缓存的命中率就会很低。所以除非你有一张静态表,很长时间才会更新一次,否则建议不用查询缓存。

mysql中可以把query_cache_type设置成DEMAND,此时默认的sql就不会执行缓存,需要缓存时需要显示指定:

select SQL_CACHE * from T where ID=10

值得注意的是,再mysql8.0版本中查询缓存的功能被完全删掉了。

四、分析器

如果没有命中缓存,就开始真正的执行语句了。首先,mysql需要知道你要做什么,所以需要对sql进行解析。

分析器首先会对sql进行词法分析,mysql需要识别sql语句的字符串分别是什么,代表什么。词法分析会把例如“select”这些关键字识别出来,也会把字符串“T”识别成表名“T”。

做完词法分析后,就要做语法分析。语法分析会根据语法规则判断输入的sql语句是否满足mysql语法。比如你的“select”少了一个s,收到“You have an error in your SQL syntax"的错误提醒。关于分析器的词法分析和语法分析具体过程和实现原理可以单独写一篇文章,在之后的文章中会给出。

五、优化器

在分析器之后,mysql就知道你要做什么了。开始执行之前,还需要优化器处理。

优化器的主要作用是在表中有多个索引的时候,决定用哪个索引;或者在一个语句有多表关联(join)的时候,决定各表的连接顺序。以下面的sql语句为例子:

select * from t1 join t2 on ID where t1.c=10 and t2.d=20;

既可以从t1中取出c等于10的记录,然后再关联到t2,然后再判断t2表中d是否等于20的行;也可以从t2中取出d等于20的记录,然后再关联到t1,然后再判断t1表中的c是否等于10 。优化器会更具上两种哪个的执行效率更高而决定用哪种方案。

对于优化器一些具体的实现方案,比如怎么选择索引等,后面会再文章中解释。

六、执行器

优化器完成以后,就要到执行器的阶段了。执行器开始执行的时候会判断你对这个表是否有查询权限(如果在之前的查询缓存返回结果,会在返回结果之前也做一次权限验证)。下面是没有权限认证的一个示例:

mysql> select * from T where ID=10;

ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'T'

当验证权限之后,就会打开表继续执行,执行器会根据表的引擎定义,去使用这个引擎提供的接口。

还是以上面例子分析,假如ID字段中没有索引,则执行的流程是这样的:调用InnoDB引擎接口取这个表的第一行,判断ID值是否为10,如果不是则跳过,如果是则将 这行存在结果集中。

调用引擎接口,取下一行,判断相同的逻辑,直到取到最后一行。

执行器将上面所有的结果集返回客户端。

对于有索引的的表,执行逻辑也差不多。第一次就会执行”满足条件的第一行“接口,之后循环取“满足条件的下一行”这个接口。

在慢查询日志中,你会看见一个rows_examined的字段,该字段会表示语句执行过程中扫描了多少行。这个值是在执行器在扫描每一行的时候累加的。在有些场景下,执行器调用一次,在引擎内部则扫描了多行,因此引擎扫描行数rows_examined 并不是完全相同的。之后准备写一篇文章来讲存储引擎的内部机制,里面会有详细的说明。

七、总结

这篇文章介绍了mysql的逻辑架构,希望可以帮助大家对mysql的完整执行流程的各个阶段有一个初步的印象。对于每个阶段细节问题,将会在之后的篇幅中展开。

mysql 查询执行过程_深入浅出Mysql(一)——sql查询执行过程相关推荐

  1. 有关mysql的开发介绍_深入浅出MySQL之开发篇(二)

    继续深入了解MySQL的高级特性. 1.存储过程和函数 什么是存储过程和函数 存储过程和函数是事先经过编译并存储在数据库中的一段SQL语句的集合,调用存储过程和函数可以简化应用开发人员的很多工作,减少 ...

  2. 深入浅出mysql唐汉名_深入浅出MySQL++数据库开发、优化与管理维护+第2版+唐汉明 -- 存储引擎 - 数据类型 - 字符集和校验规则 -...

    create schema deepInMySql; use deepInMySql; -- 查看当前默认存储引擎 show variables like '%table_type%'; -- 查看当 ...

  3. mysql 查询帖子 用户_我要用sql查询出来,我所发布的帖子和我关注的用户发布的帖子,这个sql该怎么写啊?...

    select t.*from talk twhere t.user_id = 2Unionselect t.*from talk t, user_contact cwhere c.user_id =  ...

  4. mysql pool返回值_【Mysql】你知道一条查询语句是如何执行的吗?

    [Mysql]你知道一条查询语句是如何执行的吗?​mp.weixin.qq.com 前言 在默认大家学习了Mysql结构的基础上,我们来深入的解析一下sql语句在mysql中是如何流转和实现的.本文会 ...

  5. mysql 执行概况_转mysql源码分析之SQL执行过程简介

    本人打算从SQL语句的执行开始学习和分析MYSQL源码,首先了解MYSQL是如何执行一条SQL语句的,详细了解它的执行过程之后,再深入学习执行一条SQL语句的运行原理. 1)从执行一条SQL语句的堆栈 ...

  6. mysql distinct多个字段_深入浅出Mysql索引的那些事儿

    一.索引的作用 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,所以查询语句的优化显然是重中之重. 在数据 ...

  7. mysql中的运算符的执行顺序_【MySQL】执行顺序

    我去找你❤️ 我给你买❤️ 我带你去❤️ 我很爱你❤️ 我们回家❤️ 我们结婚❤️ 你听过最孤独的话是什么? 同学,code就剩你没提交了 今天讨论的话题是 MySQL执行顺序 ??? 先养眼,再看题 ...

  8. mysql的sql执行原理图_性能测试MySQL之SQL运行原理

    一,MySQL运行原理 两个一样的图 1,SQL语句执行的过程详细说明 如上图所示,当向MySQL发送一个请求的时候,MySQL到底做了什么: a, 客户端发送一条查询给服务器. b, 服务器先检查查 ...

  9. mysql sql执行过程_MySQL探秘(二):SQL语句执行过程详解

    昔日庖丁解牛,未见全牛,所赖者是其对牛内部骨架结构的了解,对于MySQL亦是如此,只有更加全面地了解SQL语句执行的每个过程,才能更好的进行SQL的设计和优化. 当希望MySQL能够以更高的性能运行查 ...

最新文章

  1. 三种字符编码:ASCII、Unicode和UTF-8
  2. 你真的理解“吃亏是福”么?
  3. linux shell中的命令自动补全(compgen complete)与 命令行参数解析
  4. u32、u16、u8 数据类型
  5. 合理提升WEB前端性能
  6. Servlet笔记之(三)
  7. 第一个python代码
  8. 编程解决素数环问题Java_回溯法解决素数环问题java实现
  9. JavaScript红宝书第四章
  10. 华为路由器Nasp设置 以及直连路由,静态路由,缺省路由,
  11. CommonAPI 使用说明文档
  12. 为什么买入不了创业版_为什么我买不了创业板?创业板开户有什么条件
  13. echarts结合阿里云地图json选择器展示地图
  14. ATTCK v10版本战术介绍—侦察
  15. 【速记】Android让View的显示超出父容器
  16. java EE技术体系——CLF平台API开发注意事项(4)——API生命周期治理简单说明
  17. ftp命令行登陆 用法指南
  18. Linux开放80端口
  19. 数据标签体系与用户画像
  20. HTML5+CSS3小实例:DNA双螺旋动画

热门文章

  1. 利用QCommonStyle绘制自定义的窗体部件
  2. Android开发之播放量点赞量打赏量收藏量单位格式化工具类
  3. mailcore -- Mail port
  4. 使用amap-js引入高德地图AMap及其UI组件AMapUI
  5. XXX集团财务决策支持系统——财务分析指标(系列五)
  6. Gartner公布2017年十大战略科技发展趋势
  7. maven远程发布jar
  8. Mvc过滤器的使用【转载】
  9. asp.net ajax1.0基础回顾(五):调用ASMX(WebService)
  10. Exception handling 笔记