一条SQL查询语句是如何执行的?

MySQL的逻辑架构

连接器

常驻进程注意事项

数据库连接对象 $dblink 虽然存在,但是数据库连接会断掉。

原因:

客户端如果太长时间没动静,连接器就会自动将它断开。这个时间是由参数 wait_timeout 控制的,默认值是 8 小时。

解决方案:

  1. 隔一短时间(小于超时时间),置空 $dblink = null

  2. 执行前检查下数据库连接是否正常:mysqli_ping

  3. 走http请求调用接口,来避免超时

解决连接过多,涨的太快的问题

  1. 定期断开长连接。使用一段时间,或者程序里面判断执行过一个占用内存的大查询后,断开连接,之后要查询再重连。

  2. 如果你用的是 MySQL 5.7 或更新版本,可以在每次执行一个比较大的操作后,通过执行 mysql_reset_connection 来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。

查询缓存

MySQL 拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过的语句及其结果可能会以 key-value 对的形式,被直接缓存在内存中。key 是查询的语句,value 是查询的结果。如果你的查询能够直接在这个缓存中找到 key,那么这个 value 就会被直接返回给客户端。 其中Key是数据库名称,客户端协议的版本等因素算出一个hash值

  1. 通过have_query_cache服务器系统变量指示查询缓存是否可用:

mysql> SHOW VARIABLES LIKE 'have_query_cache';
  1. 为了监视查询缓存性能,使用SHOW STATUS查看缓存状态变量:

mysql> SHOW STATUS LIKE 'Qcache%';

查询缓存机制失效的场景

  1. 引用了一些返回值不确定的函数

  2. 一直缓存直到cache size用完,遵循FIFO缓存策略

分析器

检查是否有语法错误

优化器

优化器是选择哪种方案的

执行器

mysql> select * from T where ID=10;
  1. 调用 InnoDB 引擎接口取这个表的第一行,判断 ID 值是不是 10,如果不是则跳过,如果是则将这行存在结果集中;

  2. 调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。

  3. 执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。

Last updated