一条SQL语句是如何执行的?
|
|
MySQL 分为Server层和存储引擎两部分。
Server 层包括连接器、查询缓存、分析器、优化器、执行器等。涵盖MySQL的大多数核心服务功能,以及所有内置函数(如日期、时间、数字和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
存储引擎是插件式的,支持InnoDB、MyISAM、Memory等。从MySQL5.5.5版本以后默认存储引擎为InnoDB。
连接器
连接器主要负责客户端和MySQL服务端进行连接的。可以通过show processlist
查看连接信息,客户端和服务端默认连接超时为8小时,可以通过过wait_timeout
参数配置。
长连接使用一段时间后会导致MySQL内存长得很快,主要是因为MySQL在执行过程中临时使用的内存是管理在连接对象里面。这些资源会在连接重新断开的时候才释放。 解决方案如下:
定期断开长连接,使用一段时间,或者程序里面判断执行过一个占用内存大的查询后,断开连接,之后要查询再重连。
MySQL5.7以后,可以在每次执行一个比较大的操作后,通过执行
mysql_reset_connection
来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。
查询缓存
之前执行的查询结果可能会以key-value对的形式缓存在内存中,如果查询能够直接在缓存中找到key,那么会直接把value返回给客户端。
*** 大多数情况下不建议使用查询缓存。***
如果表中的数据修改的比较频繁,查询缓存的命中率就会非常的低。MySQL提供了以下方式使用查询缓存:
|
|
注意: MySQL8.0版本直接将查询缓存的整块功能删掉了。
分析器
分析器主要是分析语法是否正确,如果不正确就会收到“You have an error in your SQL syntax”的错误提醒,一般语法错误会提示第一个出现错误的位置,所以你要关注的是紧接“use near”的内容。如果查询语句中包含表中不存在的字段,也是在这一步分析。
优化器
优化器的作用主要是决定使用那个索引,或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。
执行器
开始执行的时候,要先判断你对这个表有没有执行的查询权限,如果没有,就会返回没有权限的错误。使用慢SQL查询日志中看到rows_examined
字段,表示执行过程中扫描了多少行,但有些情况下执行器调用一次,在引擎内部则扫描多行,因此引擎扫描行数跟rows_examined并不是完全相同。