您现在的位置是:首页 > 学无止境 > MYSQL网站首页MYSQL SQL查询语句的执行方式

SQL查询语句的执行方式

  • 莫愁
  • MYSQL
  • 2019-04-18
简介Service层包括连接器,查询缓存,分析器,优化器,执行器等,涵盖了大部分的核心功能,所有跨存储引擎的功能都在这一部分实现,比如存储过程SP,触发器Trigger,视图View等; 存储引擎负责数据的存储和提取。其架构是插件式的,支持InnoDB,MyISAM,Memory等多种存储引擎。
字数 1096

前言

 

Mysql架构示意图:

SQL查询语句的执行方式

MySQL可以分为Server层和存储引擎层两部分;

Service层包括连接器,查询缓存,分析器,优化器,执行器等,涵盖了大部分的核心功能,所有跨存储引擎的功能都在这一部分实现,比如存储过程SP,触发器Trigger,视图View等;

存储引擎负责数据的存储和提取。其架构是插件式的,支持InnoDB,MyISAM,Memory等多种存储引擎,MySQL5.5.5版本后InnoDB成为默认的存储引擎;在创建表的时候可以使用engine=InnoDB 来执行创建表所使用的引擎;

执行过程

举例说明各个组件的工作方式及流程:

比如有以下一张表,DDL如下:

SQL语句:

连接器

第一步,先连上数据库,这个时候遇到的就是连接器。连接器负责与客户端建立连接,获取权限,维持和管理连接:

然后输入密码,如果密码不正确,那么就会提示:Access denied for user,客户端程序结束运行;

如果密码正确,连接器会到权限表中查询出用户拥有的权限,之后,这个连接中所有的判断逻辑,都依赖于这个时候读到的权限;

连接完成后,如果没有后续的操作,那么就处于空闲状态,可以通过以下命令查看:

SQL查询语句的执行方式

如果客户端没有进一步的操作,那么连接器会自动断开,这个参数是由wait_timeout控制,默认时长为8h;

在连接断开后,如果客户端再操作,那么会提示:Lost connection to MySQL server during query;

查询缓存

连接建立完成,就可以执行select语句了,执行逻辑到第二步:查询缓存;

MySQL拿到一个请求后,会先查询缓存(之前执行过的语句及其结果会以key-value的方式存储在内存中,key是查询的语句,value是查询的结果),如果能够在缓存中查询到key,那么这个value就会直接返回客户端;

如果不在缓存中,那么就会执行到后面的阶段,执行完成后执行结果会被保存在缓存中。

注意:尽量不要对更新很频繁的表进行缓存操作:因为只要对一个表进行更新,那么这个表上的所有缓存就会全部失效,因此就会存在很多缓存还未被使用就被清空的情况,这样的查询缓存命中率很低,此外,作废缓存的操作是需要并发控制的,也就是说会有锁,并发量大的时候会出现Waiting for query lock的提示;

针对以上问题,MySQL可以使用query_cache_type进行设置:

query_cache_type=0 表示关闭

query_cache_type=1 表示开启

query_cache_type=2 表示只有在select语句中指定SQL_CACHE的时候才缓存,如:

分析器

如果没有命中缓存,就需要开始执行语句,在执行之前,MySQL需要知道这条语句要做什么,于是分析器的作用就是对SQL进行解析;

分析器首先会进行“词法分析”,由于输入的是多个字符串和空格组成的SQL语句,MySQL需要知道各个字符串代表什么;

以上SQL语句就会被识别:select是一个关键字,表明是一个查询语句。接着将T识别为表明,将ID识别为列;

词法分析后的操作就是语法分析,根据词法分析的结果,词法分析器会根据语法规则,判断输入的SQL是否满足语法,如果语法错误,那么就会提示:You have an error in SQL syntax(一般语法错误会提示第一个出现错误的位置);

优化器

经过分析器,MySQL就知道这条SQL语句是要做什么了,在执行开始之前,还需要经过优化器的处理。

优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序;

如下SQL:

这条语句,既可以先从t1表中取出c=100的id值,然后根据ID进行关联t2,再判断t2的d值是不是等于20;

也可以先从t2表中取出d=20的值,再根据ID关联到t1,再判断t1中的c是不是等于100;

这两条执行方法的结果是一致的,但是效率未必,而优化器的作用就是决定使用哪一种方案;

执行器

MySQL通过分析器知道该SQL语句要做什么,而通过优化器确定了怎么做,那么就到了执行的阶段;

开始执行的时候,先判断下是否对该表有执行操作的权限,如果没有,就会提示:* command denied to user * for table *;(以上在查询缓存的时候如果命中缓存,那么会在查询缓存放回结果集的时候,做权限验证)

如果有权限,就会继续执行,打开表的时候,执行器会根据表的引擎的定义,去使用引擎提供的接口。


转载: 感谢您对莫愁个人博客网站平台的认可,非常欢迎各位朋友分享到个人站长或者朋友圈,但转载请说明文章出处“来源莫愁个人博客 https://www.mochoublog.com/study/178.html”。

文章评论

    • 评论
    人参与,条评论

技术在线

服务时间

周一至周日 12:00-22:00

关闭下雪
关闭背景特效