Mysql 逻辑架构
-
Server 层负责建立连接、分析和执行 SQL
-
存储引擎层负责数据的存储和提取。
-
大概过程
-
连接器连接
-
查询缓存
-
解析SQL
-
执行SQL
-
具体过程:
连接
-
连接器
上述命令可以查询服务连接个数还有当前状态
-
作用:跟客户端建立连接、获取权限、维持和管理连接
-
一般的命令格式: mysql -h$ip -P$port -u$user -p
-
在完成经典的TCP握手后,连接器就要开始认证你的身份,这个时候用的就是你输入的用户名和密码
-
正确:查出你拥有的权限。之后,这个连接里面的权限判断逻辑,都将依赖于此时读到的权限。
-
错误:Access denied for user 客户端程序结束执行
-
-
连接完成后,如果你没有后续的动作,这个连接就处于空闲状态
-
客户端如果太长时间没动静,连接器就会自动将它断开。这个时间是由参数wait_timeout控制的,默认值是8小时。
-
长连接是指连接成功后,如果客户端持续有请求,则一直使用同一个连接。
-
短连接则是指每次执行完很少的几次查询就断开连接,下次查询再重新建立一个。
-
尽量使用长连接。
-
出现的问题:全部使用长连接,有些时候MySQL占用内存涨得特别快,在执行过程中临时使用的内存是管理在连接对象里面的,这些资源会在连接断开的时候才释放。如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM),从现象看就是MySQL异常重启了。
-
解决方案:
-
定期断开长连接。
-
如果你用的是MySQL 5.7或更新版本,可以在每次执行一个比较大的操作后,通过执行 mysql_reset_connection来重新初始化连接资源。
-
-
-
-
如果一个用户已经建立了连接,即使管理员中途修改了该用户的权限,也不会影响已经存在连接的权限。修改完成后,只有再新建的连接才会使用新的权限设置。
-
查询缓存
-
查询缓存
-
MySQL拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过的语句及其结果可能会以key-value对的形式,被直接缓存在内存中。
-
key是查询的语句,value是查询的结果。
-
如果查询命中缓存,MySQL不需要执行后面的复杂操作,就可以直接返回结果,这个效率会很高。
-
查询缓存往往弊大于利
-
查询缓存的失效非常频繁
-
有对一个表的更新,这个表上所有的查询缓存都会被清空
-
-
查询缓存的命中率会非常低
-
MySQL也提供了这种“按需使用”的方式,将参数query_cache_type设置成DEMAND,对于默认的SQL语句都不使用查询缓存。
-
MySQL 8.0版本直接将查询缓存的整块功能删掉了,也就是说8.0开始彻底没有这个功能了。
-
-
解析SQL
-
分析器
-
知道你要做什么,因此需要对SQL语句做解析。
-
分析器先会做“词法分析”:MySQL 会根据你输入的字符串识别出关键字出来。
-
再做“语法分析”:语法解析器会根据语法规则,判断你输入的这个 SQL 语句是否满足 MySQL 语法。
-
错误提示:You have an error in your SQL syntax
-
一般语法错误会提示第一个出现错误的位置,所以你要关注的是紧接“use near”的内容。
-
-
构建的 SQL 语法树
-
执行SQL
-
预处理器
-
检查 SQL 查询语句中的表或者字段是否存在。
-
-
优化器
-
优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。
-
执行方法的逻辑结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择使用哪一个方案。
-
-
执行器
-
开始执行语句
-
先判断一下你对这个表T有没有执行查询的权限。
-
打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。
-
慢查询日志中看到一个rows_examined的字段,表示这个语句执行过程中扫描了多少行。这个值就是在执行器每次调用引擎获取数据行的时候累加的。
-
在有些场景下,执行器调用一次,在引擎内部则扫描了多行,因此引擎扫描行数跟rows_examined并不是完全相同的。
-
-
-
在执行的过程中,执行器就会和存储引擎交互了,交互是以记录为单位的。
-
执行过程
-
主键索引查询
-
让存储引擎定位符合条件的第一条记录。
-
-
全表扫描
-
让存储引擎读取表中的第一条记录。
-
-
索引下推
-
将 Server 层部分负责的事情,交给存储引擎层去处理了
-
减少二级索引在查询时的回表操作,提高查询的效率。
-
-
-