一、Mysql基础架构(Mysql实战45讲笔记-基础)
1. Mysql基础架构:sql查询语句的执行过程
1.1 MySQL基本架构
Mysql分为:
- Server层:包含所有内置函数,所有跨存储引擎的功能都在这一层:存储过程、触发器、视图等
- 连接器
- 查询缓存
- 分析器
- 优化器
- 执行器
- 存储引擎层:负责数据的存储和提取,是插件式的,支持InnoDB、MyISAM、Memory等
- Mysql5.5.5之后,InnoDB是默认的存储引擎,也是最常用的
- 创建表的之后,可以指定其他存储引擎,例如:
engine=memory
1.2 连接器
连接器负责和客户端建立连接、获取权限、维护和管理连接。
# 连接命令,密码不建议直接跟在-p 后,因为通过查看历史命令,就泄露了密码
mysql -h$ip -P$port -u$user -p
#例如
mysql -u root -p
连接命令中的mysql 是客户端工具,用来和服务端建立连接,通过tcp建立连接,之后开始根据输入的账号密码认证身份:
- 用户名、密码不对:返回错误提示客户端程序结束执行。
- 认证正确:连接器去权限表查出所有拥有权限。
注意:一个用户连接成功后,对该用户的权限做修改,不生效,需要重新建立连接。
通过show processlist
命令可以查看空闲状态的连接,就是不进行操作的连接,如果客户端一直不操作,连接器会自动断开,通过wait_timeout
设置等待时间,默认是8h。
长连接:
- 连接成功后,一直使用同一个连接
- 使用长连接,可以减少多次连接的操作
- 全部使用长连接,mysql内存占用会过多,因为mysql执行过程中临时使用的内存管理是在连接对象中的,只有断开连接的时候,占用的内存才会释放,如果都使用长连接,那可能会导致内存占用太大,oom后会被系统强行杀掉,表现就是Mysql异常重启
利用长连接提高效率的解决方案:
- 定期断开长连接,或者程序中判断执行一个占用内存的大查询后,断开连接
- Mysql5.7后,可以在每次执行一个占用内存的操作后,执行
mysql_reset_connection
来重新初始化连接资源,这个过程不需要做重连和重新获取权限,但是内存会被释放
1.3 查询缓存(mysql8.0之后没有这个功能了)
mysql执行过的语句和结果会以key-value对的形式,缓存在内存中,之后再执行同样的语句,可以直接从缓存中获取。
但是一个表被更新的时候,该表的所有缓存都清空,缓存命中率很低,只有静态表(不被修改,只被查询)才适合使用查询缓存。
通过设置参数query_cache_type=DEMAND
,默认不使用缓存,想要使用缓存的时候,通过SQL_CACHE
显式指定。(mysql8.0之后就没了)
# 指定使用缓存查询
select SQL_CACHE * from t where id=1;
1.4 分析器
- 首先识别执行语句中得关键字
- 做语法分析,不符合sql语法及提示错误信息
1.5 优化器
- 选择索引:表中有多个索引时,选择使用的索引
- 多表关联时,决定表的连接顺序
1.6 执行器
-
首先判断你的权限,没有权限则返回错误信息(如果命中缓存,则在查缓存前就做权限校验),这个过程叫 precheck
-
执行器调用存储引擎接口获取数据
例如:
select * from T where k=10;
k没有索引的的执行步骤-
调用存储引擎获取表的第一行,判断k是不是10,不是则跳过,是的话则将这行存入结果集
-
调用引擎取下一行,重复的判断逻辑,知道取到这表的最后一行
-
执行起完成上述遍历,将所有满足条件的行组成的结果集返回到客户端
若k存在索引,则调用引擎接口“取满足条件的第一行”、“取满足条件的下一行”,这个是存储引擎提供的,根据索引过滤是在存储引擎中处理的
-
根据数据库的慢查询日志,rows_examined 字段,表示的是执行器每次调用引擎获取数据行的次数,而不是实际引擎扫描的行数。