• MySQL的体系结构,可以清楚地看到 SQL 语句在 MySQL 的各个功能模块中的执行过程:Server层包括连接层、查询缓存、分析器、优化器、执行器等,涵盖MySQL的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),实现所有跨存储引擎的功能比如存储过程、触发器、视图等;存储引擎层负责数据的存储和提取,MySQL5.5.5版本开始默认使用InnoDB,即你执行create table建表时,不指定引擎类型,默认使用InnoDB;

    • 连接器:

      • 连接管理(Connection Handling):当一个客户端进行连接服务端时,会得到一个server处理线程,每个连接的请求处理都是单线程的,同时服务器会缓存这些线程,所以当一个新的连接来时就不需要创建和销毁线程【MySQL5.5及其以上版本提供了一个支持线程池插件的接口】;
      • 权限认证(Authentication):当客户端连接服务端时,服务端需要对连接进行认证,即对username、host、password进行认证;
      • 安全(Securith):当客户端成功连接上服务端时,服务端会对每个连接查看它的系统权限清单【mysql> show privileges \G】,之后这个连接里面的权限判断逻辑,都将依赖于此时读到的权限,即一个用户成功建立连接后,即使对这个用户的权限做了修改,也不会影响到已经存在连接的权限,修改完后,只有再新建的连接才会使用新的权限设置;
      • 备注:
        • 连接完成后,如果没有后续的操作,这个连接就处于空闲状态,可以使用show processlist进行查看,当Command列中出现Sleep时表示该连接是空闲状态;客户端如果太长时间没有动静,连接器会自动断开连接,这个时间由参数wait_timeout控制,默认值是8小时,如果在连接被断开后,客户端再次发起请求,会收到一个错误提醒:Lost connection to MySQL server during query。这时候如果要继续,就需要重连,然后再执行请求;
        • 数据库里面的长连接成功后,如果客户端持续有请求,则一直使用同一个连接;短连接则是每次执行完很少的几次查询就断开连接,下次查询再重新建立一个;
        • 全部使用长连接后,有时候MySQL占用内存涨的很快,这是因为MySQL在执行过程中临时使用的内存是管理在连接对象中的,这些资源在断开时才会被释放,如果长连接累计下来,可能导致内存占用太大,被系统强行杀掉(OOM),从现象看就是MySQL异常重启了;
          • 解决方案1:定期断开长连接。使用一段时间或程序里面判断执行过一个占用内存的大查询后,断开连接,之后要查询再重连;
          • 解决方案2:MySQL版本如果是5.7及其以上,可以在每次执行一个大的操作后,通过执行mysql_reset_connection来重新初始化连接资源。这个过程不需要重连和做权限验证,会将连接恢复到刚刚创建完时的状态。
    • 分析器(Parser):MySQL分析器会创建一个内部结构(解析树),MySQL的解析行为就像单趟编译器一样,进行词法解析、语法解析、语义解析;
      • 词法解析:MySQL对语句进行识别里面的字符串分别是什么,代表什么,比如”select“是一个查询语句,吧字符串”tableName"识别为“表名 tableName",吧字符串”id“识别成”列id";
      • 语法解析:根据语法规则,判断输入的SQL语句是否满足MySQL语法,比如“elect *from tableName"这个会提示”You hava an error in your SQL syntax“的错误提醒;一般语法错误会提示第一个出现错误的位置,所以要关注的是紧接”use near"的内容;
    • 优化器(Optimizer):当创建完解析树后,服务端会进行一系列的优化操作,包括重写查询语句、确定读表的顺序、索引选择等等,你可以使用explain进行查看细节【MySQL笔记(3)-- SQL分析】;
    • 缓冲器(Caches):缓冲器会缓存查询的结果集,当进行查询解析前,服务端会去缓存器查找,如果改查询命中缓存,那就不需要进行解析、优化、执行等等操作,直接返回缓存结果集;【以key-value保存执行过的语句及查询结果,如果对表进行了更新操作,该表的所有查询缓存都会清空】
    • 执行器:开始执行时,需要先判断你有没有这个表的执行权限,如果没有,返回没有权限的错误【同时对于命中查询缓存,会在查询缓存返回结果时做权限验证,查询会在优化器之前调用precheck验证权限】,如果有权限,打开表继续执行,执行器根据表的引擎定义,去使用这个引擎提供的接口,比如查询语句select *from table where id=1;中的id字段没有索引,那么执行器的执行流程是
      1. 调用InnoDB引擎接口取这个表的第一行,判断id是不是1,如果不是则跳过,如果是则将这行存在结果集中;
      2. 调用引擎接口取”下一行“,重复相同的判断逻辑,直到取到这个表的最后一行;
      3. 执行器将上述遍历过程中所有满足条件的行组成的结果集返回给客户端;

最新文章

  1. OAF 中的EO 和VO
  2. MVC之前的那点事儿系列(1):进入CLR
  3. golang debug with LiteIDE
  4. Linux-记录一次被当肉鸡行为
  5. 导出Excel之Epplus使用教程4(其他设置)
  6. AltiumDesigner学习笔记(一)——创建工程与原理图文件
  7. MVC Area Usage
  8. JAVA Exchanger
  9. Java程序设计的基本原则
  10. python (2)xpath与定向爬虫
  11. Python 网页投票信息抓取
  12. [Express] Level 2: Middleware -- 2
  13. WinDriver&PCIE
  14. HW4.43
  15. hdu 2711&&poj2182 Lost Cows (线段树)
  16. PostBack与IsPostBack区别
  17. 多少遍ner让他加56看6
  18. 关于修改编JDK编译环境的问题
  19. C#用正则表达式替换手机中间几位为*号 代码及解析
  20. python用字符串调用当前模块内的函数

热门文章

  1. Ionic3学习笔记(十二)拍照上传图片以及从相册选择图片上传
  2. Python 搭建webdriver环境遇到的问题总结
  3. 题解 P1951 【收费站_NOI导刊2009提高(2)】
  4. 每天一个linux命令(15)-tail
  5. kafka Py客户端
  6. linux下大文件处理
  7. C:指针习题
  8. Leetcode 24题 两两交换链表中的节点(Swap Nodes in Pairs))Java语言求解
  9. nginx 命令行参数 启动 重启 重载 停止
  10. 【Mood】八上期末考