MySQL的结构
mysql结构可以分为两层,从上至下分别是:
- Server层
- 存储引擎层
Server层
连接器
当一条查询语句执行前,首先要建立客户端和MySQL之间的连接🔗(连接器)
- 是通过tcp三次握手建立连接,连接建立后,通过验证 mysql -u username -p pswd 中的用户名和密码来认证身份,查询该身份对应的权限,值得一提的是,整个连接使用直到下次连接开始之前,对身份权限的判断只在这个时候执行一次,因此一旦建立连接后,即使管理员修改了用户的权限,也只有在下次连接时得到体现
- 连接建立后,如果没有后续的操作,且连接建立的时间小于阈值(wait_timeOut,默认8小时),那么这个连接处于空闲状态(可以通过show processlist命令中看到该连接的 Command为Sleep)
- 建立连接的过程十分复杂,应该避免频繁的建立连接,因此推荐使用长连接,长连接是指连接成功后,在阈值内如果客户端持续有请求,那么就维持这个连接,相反,短连接则是每次执行完很少几次查询就断开连接。但是全部建立长连接的话,对内存的消耗可能会比较大,解决方案:
- 定期断开长连接
- 如果mysql版本>= 5.7 ,通过执行mysql_reset_connection来重新初始化连接资源,这个过程不需要重连和重新做权限验证,会将连接恢复到刚刚创建完成时的状态。
查询缓存
然后去缓存里查找是否已经执行过这条命令了,如果hit到了缓存,则直接返回查询结果,这也是为什么有时候同一条语句第二次执行速度明显快很多的原因。
其实不是很推荐使用缓存功能,因为一旦对表内的元素执行过写操作,那么缓存就会被清空,对于写压力大的数据库而言,查询缓存的命中率会非常低。 除非是经常读不常写的表(系统配置表),mysql也提供了缓存开关(query_cache_type)
分析器
如果没有命中缓存,那么就该分析分析这条sql语句要干啥了,编译原理告诉我们,对语句分析分成三个过程:词法分析、语法分析、语义分析,其实mysql中的分析器也就是干这三件事情。
优化器
有些语句的逻辑相同但是执行效率会有差别,优化器就是决定使用哪一种方案。
执行器
上面的准备工作都干完了,就该切入正题了,不过在执行之前,执行器会先去检查一下用户是否有执行上述语句的权限(如果命中缓存,会在返回结果前进行权限验证)。
如果有权限,那么就打开表,执行器根据表的引擎定义,使用引擎提供的借口。