1.整体结构
从图上看MySQL大体结构分为 server层 和 引擎层。
Server层:主要包括连接器、分析器、优化器、执行器、查询缓存等,涵盖mysql核心功能,所有的跨存储引擎功能都在这一层实现(存储过程、视图、触发器以及一些内置函数等)。
存储引擎:负责数据的存储和提取,支持不同种类的存储引擎类型以插件模式进行嵌入。目前支持InnoDB(5.5.5版本开始成为默认引擎)、MyISAM、Memory等引擎。
2.连接器
负责与客户端建立连接、权限获取、管理连接等。
mysql -h$ip -P$port -u$user -p
用户密码验证通过,连接器去权限表查询你的权限。此次建立起的连接,里面的权限逻辑判断,都依赖于此时读到的权限。即使,此刻管理员对你的权限做了修改都无济于事。只有新建的连接才会使用新的权限设置。
wait_timeout:默认8小时,客户端太长时间没连接,连接器会自动断开
长连接:连接成功后,若客户端有持续请求,一直使用同个连接(推荐使用) 短连接:,每次执行完很少的几次查询就断开。
mysql在执行过程中临时使用的内存是管理在连接对象里面,所以使用长连接有时候占内存,直到断开连接后才会释放。 内存占用太大,系统强行kill,导致mysql异常重启。
解决方案:
1.定期断开长连接: 定期断开或程序判断执行占用内存比较大的查询后断开等
2.在每次执行一个比较大的操作后,通过执行 mysql_reset_connection 来重新初始化连接资源
3.查询缓存
以如下查询语句为例:
mysql> select * from T where ID=10;
查询请求进来,会先去缓存查找,之前是否执行过该条语句(key:查询语句 value:查询结果) 如果不在缓存,继续执行后面操作,然后再入缓存
虽然效率高,但是不建议使用。因为查询缓存失效较频繁,只要有对表进行更新,该表上的查询缓存都会被清空。对于频繁更新操作的数据库来说,查询缓存的命中率低。 适合一些静态表使用(很长时间才会更新一次,系统配置表等). 此外,MySQL 8.0 版本直接将查询缓存的整块功能删掉
query_cache_type:DEMAND 查询语句默认不走缓存
可以指定语句
mysql> select SQL_CACHE * from T where ID=10;
4.分析器
主要负责对sql语句进行解析,分析这条sql到底要做什么。 词法分析(解析关键字)-> 语法分析(语句是否正确)
5.优化器
主要工作:判断走哪个索引、连表查询时决定各个表的连接顺序等。总而言之,就是确定sql的执行方案,选择最优的方案尽可能的让查询语句更高效
6.执行器
MySQL 通过分析器知道了你要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段,开始执行语句。
mysql> select * from T where ID=10; (假设id无索引)
执行流程:
- 调用InnoDB引擎接口,取此表第一行,判断ID是不是等于0。不是则跳过,是则保存在结果集合执行
- 继续调用接口取下一行,继续判断,直到结束
- 执行器将所有满足条件的行组成的记录集返回给客户端
对于有索引的表,执行的逻辑也差不多。第一次调用的是“取满足条件的第一行”这个接口,之后循环取“满足条件的下一行”这个接口,这些接口都是引擎中已经定义好的。
注:此文章仅作为个人的学习笔记。文章借鉴于林晓斌(丁奇)老师的“MySQL实战45讲”。 摘自:time.geekbang.org/column/intr…