mysql结构
先来简单看一下mysql的基本结构
大体来说,MySQL 可以分为 Server 层和存储引擎层两个部分
Server层
包括:连接器、查询缓存、分析器、优化器、执行器等核心服务功能,所有跨存储引擎的功能都在这一层实现:存储过程、触发器、视图等。
连接器:负责跟客户端建立连接、维持和管理连接
数据库连接器会为每个连接请求分配一块专用的内存空间用于会话上下文管理。建立连接对数据库而言相对比较重,需要花费一定的时间,因此应用程序启动的时候,通常会初始化建立一些数据库连接放在连接池里,这样当处理外部请求执行SQL操作的时候,就不需要花费时间建立连接了。
这些连接一旦建立,不管是否有SQL执行,都会消耗一定的数据库内存资源,所以对于一个大规模互联网应用集群来说,如果启动了很多应用程序实例,这些程序每个都会和数据库建立若干个连接,即使不提交SQL到数据库执行,也就会对数据库产生很大的压力。
查询缓存:以(key,value)的形式存储执行过的语句和结果
查询缓存不在上图中,是从 4.1 版本开始支持,默认是关闭的,可以在运行时设置变量set query_cache_type=1开启,也可以重写配置文件中的参数开启。一般不建议开启,因为只要更新缓存就会被全部清空
分析器:词法分析、语法分析
语法分析器工作比较简单机械,就是根据SQL语法规则生成对应的抽象语法树。如果SQL语句中存在语法错误,那么在生成语法树的时候就会报错
这个阶段会检查:1)是否使用了错误的关键字;2)使用的关键字顺序是否正确;3)检查数据表和数据列是否存在等
优化器:生成最优的执行计划,包括索引选择、join 表的顺序等
一般情况下,一条查询可以有多种执行方法,最后都是返回相同结果。优化器的作用就是找到这其中最好的执行计划。
MySQL使用基于成本的查询优化器。它会根据统计信息和代价模型预测一个查询使用某种执行计划时的成本,并选择其中成本最少的一个。
例如 select * from XX where a=1 and b=2;
有b,a的联合索引,那么优化器会自动调整为where b=2 and a=1去走索引
执行器:操作存储引擎,返回结果
通过调用存储引擎定义好的API,操作存储引擎,并将结果返回给客户端。
存储引擎层
通过提供读写接口,来负责数据的存储和提取。
其架构模式是插件式的,支持Innodb、MyISAM等存储引擎,其中Innodb是最常用的存储引擎。
执行过程
假设当客户端和服务端建立连接之后,客户端向服务端发送如下一个(查询)请求
select * from DB where a = 1 and b = 2;
MySQL的执行路径如下:
1、如果查询缓存是打开的,服务器端会优先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果。否则进入下一阶段。
2、服务器端的分析器对SQL进行词法分析、语法分析,再由优化器从存储引擎获取统计信息,根据代价模型生成对应的执行计划(确定走不走索引,怎么走最优)
3、服务器端根据优化器生成的执行计划,再调用存储引擎的API来执行查询,并将结果返回给客户端,具体如下
3.1)调用InnoDB存储引擎的接口取满足”a=1“条件的第一条记录返回给执行器
3.2)执行器判断该记录中的b字段是否等于2,如果不等于则跳过,否则放入结果集
3.3)调用InnoDB存储引擎的接口取满足“a=1”条件的下一条记录并返回给执行器
3.4)重复第二、三步,直至循环遍历结束
3.5)执行器将结果集返回给客户端
注:MySQL将结果返回客户端是一个增量、逐步返回的过程,并不一定等到所有的结果集都查出来再返回。
这样处理有两个好处:
1)服务器无需存储太多的结果,也就不会因为要返回太多的结果而消耗太多的内存;
2)这样的处理也让MySQL客户端第一时间获得返回的结果