0x01-基础架构-一条SQL查询语句是如何执行的

/ MySQL / 1 条评论 / 461浏览

MySQL的逻辑架构图

image

Server层


包括连接器、查询缓存、分析器、优化器、执行器,涵盖MySQL的大多数核心服务功能,以及所有的内置函数(如日期、时间、数据和加密函数等),所有跨存储引擎的功能(比如存储过程、触发器、视图等)

  1. 连接器

    连接器负责跟客户端建立连接、获取权限、维持和管理连接。

    连接器会到权限表里查用户的权限,整个连接里的权限判断逻辑都依赖于此时读到的权限,==如果用管理员账号对用户的权限做 了修改,也不会影响已有的连接的权限==

    show processlist 显示连接。Command列显示为“Sleep”的表示存在空闲的连接。 客户端如果长时间不操作,连接器会自动断开,时间参数由wait_timeout控制,默认值为8小时连接命令:

mysql -h$ip -P$port -u$user -p
1. 长连接: 连接成功后,如果客户端持续有请求,则一直使用同一个连接

2. 短连接:每次执行完很少的几次查询就断开连接,下次查询再重新建立一个

3. 建立的过程通常比较复杂,因此尽量使用长连接。

4. 长连接会造成MySQL占用内存上升,因为MySQL在执行过程中临时使用的内存是管理在连接对象里面的,连接释放时释放。如果内存占用太高,被系统强行杀死(OOM),从现象看就是MySQL异常重启了。解决办法:

    1. 定期断开长连接,或在程序里判断执行过一个占用内存的大查询后,断开连接,之后查询重新再连
    
    2. MySQL 5.7及以上版本,可以在执行一个比较大的操作后,通过执行mysql_reset_connection来初始化连接,这个过程不会重连和权限验证。
  1. 查询缓存

    之前执行过的sql语句及其结果以key-value对的方式被直接缓存在内存中

    命中缓存后MySQL不需要执行后面的复杂的操作,直接返回结果

大多数情况下不建议使用,查询缓存往往利大于弊,8.0以上版本没有查询缓存功能

> 查询缓存的失效非常频繁,只要有对一个表的更新,则该表上所有的查询缓存都会被清空,只有比如系统配置表这样的更新较少的表,才适合使用查询缓存

> query_cache_type设置为DEMAND,这样对于默认的SQL都不使用查询缓存。对于使用查询缓存的语句,可以使用SQL_CACHE显示指定(query_cache_type有三个取值:0,1,2,分别代表了off、on、demand)
select SQL_CACHE * from T where ID=?;
  1. 分析器

    1. 词法分析

    如识别到“select”,这是一个查询语句。识别字符串“T”为表名“T”,字符串“ID”为“列ID”.

    1. 语法分析

    依据语法规则,分析是否符合MySQL语法

  2. 优化器

    优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联的时候,决定各个表的连接顺序。

  3. 执行器

    执行前先判断对这个表T有没有执行查询的权限,如果没有则返回command denied错误

    调用存储引擎,重复执行取下一行操作,直至最后表一行记录。数据库的慢查询日志中rows_examined含义:表示该语句执行过程中扫描的行数。 rows_examined与引擎扫描行数不完全相同。

存储引擎层


负责数据的存储和提取。架构模式是插件式的,支持InnoDB(5.5.5版本后为默认存储引擎)、MyISAM、Memory等多个存储引擎。

在 create table语句中使用engine=memory,来指定使用内存引