当你希望 MySQL 能够以更高的性能运行查询时, 最好的办法是弄清楚 MySQL 是如何优化和执行查询高性能 MySQL
MySQL 客户端与服务器端的通信特点
客户端与服务器之间是半双工通信, 意味着服务器与客户端之间的传递数据不可以同时发生
客户端使用一个单独的数据包将查询传给服务器当语句过长时, 可能受到服务器端 max_allowed_packet 的限制
服务器响应给用户的数据通常会很多, 由多个数据包组成 (客户端不断接受服务器推送的数据, 客户端没有办法让服务器停下来客户端像是从消防水管喝水)
连接数据库的库函数缓存获取的数据库函数需要花费很多时间和内存来存储结果集
不使用缓存来记录结果而是直接处理服务器的资源一直被查询占用, 不利于并发操作
查询的执行流程
图一 语句的处理过程
1. 连接数据库
客户端发起一条 Query 请求, 监听客户端的连接管理模块接收请求
将请求转发到连接进 / 线程模块
调用用户模块来进行授权检查
通过检查后, 连接进 / 线程模块从线程连接池中取出空闲的被缓存的连接线程和客户端请求对接, 如果失败则创建一个新的连接请求
2. 处理请求
查询缓存 通过一个大小写敏感的哈希查找判断查询是否命中查询缓存的数据
命中查询缓存, 用户权限没有问题, MySQL 直接从缓存中拿结果返回给客户端
查询优化处理 (解析 SQL 预处理优化 SQL 的执行计划), 将 SQL 转化成一个执行计划
解析和预处理: 生成一棵解析树 (编译原理的知识),MySQL 按照其语法对解析树进行验证和解析查询判断语法是否合法
将语法树转化为执行计划 (子任务), 并选择成本尽量小的执行计划
优化过程书上介绍了很多情况, 请参考书籍 6.43 章
执行计划 MySQL 会生成一个指令树, 然后通过存储引擎完成这棵树并返回结果 如图 2
查询执行引擎 查询执行引擎则根据执行计划来完成整个查询在执行计划时, 存储引擎通过调用实现的接口来完成
图二 四个表的表连接查询的执行计划指令树
3. 返回结果
如果查询可以被缓存, MySQL 将结果存放到查询缓存里
MySQL 将结果集返回给客户端是一个逐步返回的过程; 数据库开始产生第一个结果时, 就可以开始向服务器返回结果集
使用 MySQL 客户端服务器通信协议进行封包
通过 Tcp 协议传输数据
来源: https://www.cnblogs.com/yweihum/p/8643173.html