0.说明
某次组会分享的内容:mysql查询语句的底层执行
1.mysql的逻辑结构
- 客户端主要指的是连接mysql的应用,主要包括 Navicat 系统 命令行等等;
- server层是mysql的核心部分,不同存储引擎共用一个Server层:包括连接器 查询缓存 分析器 优化器 执行器等。涵盖mysql大部分的核心服务功能,以及所有的内置函数(日期,时间,数学和加密函数等),所有哦跨存储引擎的功能都是这层实现,比如存储过程,触发器,视图等等。
- 存储引擎层: 主要是底层数据存取操作的实现部分,由多个存储引擎组成,他们负责存储和获取所有存储在mysql中的数据。
2.不同客户端连接数据库
连接器:负责和客户端建立连接,获取权限,维持和管理连接。
连接命令
mysql -h$ip -P$port -u$user -p
输入密码
连接器完成经典TCP握手,验证身份:
1.用户名密码验证 2.加载权限
3.连接器在连接过程中做了什么?
连接器接收到客户端的连接请求响应主要包括5个步骤:
- 客户端发送连接请求
- 连接器接收并创建连接对象
- 连接器去系统数据库load user的权限
- 把user的权限加载到连接对象
- 连接器返回连接对象给客户端
4.如果客户端连接成功并获得连接对象,中途修改user表的权限,连接对象的权限是否受影响?
4.1 长连接
因为建立连接的过程比较复杂,所以一般尽量减少连接的动作,也就使用长连接。
但是使用长连接,会发现有时候Mysql占用内存涨的很快。(因为mysql在执行过程中临时使用的内存是管理在连接对象里面的,这些对象只有断开连接才会被释放,所以长时间连接累积,导致内存占用太大,被系统强行杀掉(OOM),从现象看就是mysql的异常重启)
两种解决方案:
1.定期断开长连接
2.mysql5.7以上 使用mysql_reset_connection重新初始化连接资源,这个过程不需要重连或者重新做权限验证。但是会将连接恢复到刚刚创建完的状态。
5.一条语句的执行过程-语法分析器
MySQL 从你输入的"select"这个关键字识别出来,这是一个查询语句。它也要把字符串“T”识别成“表名 T”,把字符串“ID”识别成“列 ID”。做完了这些识别以后,就要做“语法分析”。根据词法分析的结果,语法分析器会根据语法规则,判断你输入的这个 SQL 语句是否满足 MySQL 语法。
6.一条语句的执行过程-语义检查
7.一条语句的执行过程-优化器
其中,逻辑查询优化将生成逻辑查询执行计划。根据关系代数的原理,把语法分析树变为关系代数语法树的样式,原先SQL语义中的一些谓词变化为逻辑代数的操作符等样式
这些样式是一个临时的中间状态,经过进一步的逻辑查询优化,如执行常量传递、选择下推等(如一些节点下移,一些节点上移),从而生成逻辑查询执行计划。
物理查询优化除了进行表的连接顺序调整外,还会使用代价估算模型对单个表的扫描方式、两表连接的连接算法进行评估,选择每一项操作中代价最小的操作为下一步优化的基础。物理查询优化的最终结果是生成最终物理查询执行计划。
8.一条语句的执行过程-执行器
mysql的存储引擎 是按照插件的形式,提供一个接口给server层去用,这样的一个好处是,在执行器调用引擎接口的时候,我们可以动态的扩展数据库存储引擎或者是动态组合存储引擎,可扩展性比较高。
9.一条语句的执行过程-存储引擎
10.一条语句的执行过程-缓存区
如果中途没有update或者insert操作,是第二次查询的话,会直接去缓存区读取这个结果(key-value key是查询语句,value是查询的结果)。避免了磁盘IO,大大提高了数据库处理查询的能力。
但是如果中途有update或者insert操作。在一个表上有更新的时候,跟这个表有关的查询缓存会失效,如果是写多读少的应用场景的话,效率比较慢。这也就是我们一般不建议使用查询缓存的原因
query_cache_type=0时表示关闭,1时表示打开,2表示只要select中明确指定SQL_CACHE才缓存。
查看缓存运行状态 :比如你想执行某个查询之前,你可以查看缓存运行状态
11.分享一张mysql生态图
12.总结
- 关系代数、查询优化、代价估算模型等等内容对于mysql的优化器部分理解是非常有用的
- 关于update及delete语句还有关于binlog以及redo log的部分需要探索