这篇文章上次修改于 2037 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

基于mysql> select * from T where ID = 10;简略分析mysql走过的流程。 首先mysql 是分层的,查询语句首先经过server 层,然后进入存储引擎层(innodb)。 server 层又分为流程: 连接器—-查询缓存——-分析器——-优化器—-执行器。引擎层可以是innodb和myisam 等,它们共用一个server

第一步。连接器——负责和客户端建立连接(TCP握手),验证获取权限,维持和管理连接

  • 连接命令 mysql -h $ip -P port -u User -p password ,mysql客户端首先完成3次握手,然后发送用户名密码。
  • 验证成功后,读取相应权限放到连接中(注意后续的更改权限不会影响此次连接)
  • 一般采用长连接,比较高效。
  • 连接器会定时检查连接的时间,超过8个小时没有活动的连接会被关闭掉
  • 可以用show processes 查看所有的连接。
  • 连接会占用系统资源,如果进行了一个比较大的操作,可以执行mysql_reset_connection,重置连接,释放资源

第二步。 查询缓存,(注意mysql8之后,去掉了缓存,所以没有这一步)。

  • mysql 语句和结果,会以key value的形式存在于内存中,如果sql语句命中缓存,则直接返回
  • 对一个表的更新。会清理这个表的所有缓存,所以,经常更新的表不要使用缓存。
  • query_cache_type 这个系统变量控制着查询缓存工能的开启的关闭,query_cache_type=0时表示关闭,1时表示打开,2表示只要select 中明确指定SQL_CACHE才缓存

第三步。 分析器,对SQL语句进行解析,类似编译原理的前期阶段。

  • 词法分析,分析语句有哪些词(编译原理叫token)

  • 语法分析,判断是否符合mysql 语法规则,如果不满足,报错:You have an error in your SQL syntax

第三步。 优化器,在语句被执行之前,优化执行过程达到更好的效率。

  • 决定使用哪个索引
  • 决定表的连接join顺序

第四步。 执行器 开始执行语句,调用引擎层

  • 执行器先判断权限,如果没有权限,返回错误。(这一步不在前面做,有些触发器在执行阶段才知道)
  • 调用innodb引擎的接口获取一条数据,然后循环取满足条件的下一行
  • 最后将结果返回给前端。