一、Mysql基础架构(Mysql实战45讲笔记-基础)

1. Mysql基础架构:sql查询语句的执行过程

1.1 MySQL基本架构

image-20210413161115604

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异常重启

利用长连接提高效率的解决方案:

  1. 定期断开长连接,或者程序中判断执行一个占用内存的大查询后,断开连接
  2. 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 分析器

  1. 首先识别执行语句中得关键字
  2. 做语法分析,不符合sql语法及提示错误信息

1.5 优化器

  1. 选择索引:表中有多个索引时,选择使用的索引
  2. 多表关联时,决定表的连接顺序

1.6 执行器

  1. 首先判断你的权限,没有权限则返回错误信息(如果命中缓存,则在查缓存前就做权限校验),这个过程叫 precheck

  2. 执行器调用存储引擎接口获取数据

    ​ 例如:select * from T where k=10; k没有索引的的执行步骤

    1. 调用存储引擎获取表的第一行,判断k是不是10,不是则跳过,是的话则将这行存入结果集

    2. 调用引擎取下一行,重复的判断逻辑,知道取到这表的最后一行

    3. 执行起完成上述遍历,将所有满足条件的行组成的结果集返回到客户端

      若k存在索引,则调用引擎接口“取满足条件的第一行”、“取满足条件的下一行”,这个是存储引擎提供的,根据索引过滤是在存储引擎中处理的

根据数据库的慢查询日志,rows_examined 字段,表示的是执行器每次调用引擎获取数据行的次数,而不是实际引擎扫描的行数。

原文地址:https://www.cnblogs.com/zhaoyuan72/p/14666190.html