一 、SQL 语句生命周期
mysql 启动以后,初始化模块就从系统配置文件中读取系统参数和命令参数,初始化整个系统,同时存储引擎也会启动;
- 初始化结束后,连接管理模块会监听客户端的连接请求,并将连接请求转发给线程管理模块去请求一个连接线程;
- 线程模块接到请求后会调用用户模块进行授权检查,通过授权以后会检查是否又空闲线程,如果有取出并与客户端连接,如果没有则新建立建立一个线程与客户端连接;
- mysql 请求分为两种
- 一种是需要命令解析和分发才能执行
- 另一种可以直接执行;不管哪种,如果开启了日志,那么日志模块会记录日志;
- 如果是 Query 类型的请求,会将控制权交给 Query 解析器,Query 解析器检查是否 Select 类型,如果是则启动查询缓存模块,如果缓存命中则将缓存数据返回给连接线程模块,连接线程将数据传递到客户端;如果没有缓存或者不是一个可以缓存的查询,此时解析器会进行相应的处理,通过查询分发器给相关的处理模块;
- 如果解析器结果是 DML/DDL,则交给变更模块;如果是检查、修复的查询交给表维护模块,如果是一条没有被缓存的语句,则交给查询优化器模块。实际上表变更模块又分为若干小模块,
- 例如:insert 处理器、delete 处理器、update 处理器、create 处理器,以及 alter处理器这些小模块来负责不同的 DML 和 DDL。
- 总之,查询优化器、表变更模块、表维护模块、复制模块、状态模块都是根据命令解析器的结果不同而分发给不同的类型模块,最后和存储引擎进行交互读取当前 SQL 语句满足条件的数据。
- 当一条命令执行完毕后,控制权都会还给连接线程模块,在上面各个模块处理过程中都依赖于核心 API 模块,比如:内存管理、文件 I/O,字符串处理
二 、SQL 语句常见优化手段
- 不使用 select *
- 不使用 NULL 字段
- 合理地使用索引
- 为字段选择恰当的数据类型
- 最左匹配规则
- 拒绝隐式转化等等
三 、普通 SQL 如何优化?
3.1 、普通 SQL 语句优化
优化手段:ICP 、MRR 算法
3.1.1、ICP
ICP 是 MySQL 使用索引从表中检索行数据的一种优化方式。目标是减少从基表中
读取操作的数量,从而降低 I/O 的操作。
禁用 ICP,存储引擎会通过遍历索引定位基表中的行,然后返回 server 层,在对这
些数据进行 where 后的条件过滤
3.1.2、MRR
MySQL 优化器将随机 I/O 转化为顺序 I/O,目的是减少磁盘的随机访问。以降低查
询 I/O 的开销。
3.2 、 join 语句优化
采用 BKA 算法优化 jion 语句,将外部表的列放入到 join buffer 里面,然后把列数
据发送给 MRR 接口,接口根据 row id 做好排序,在进行顺序 IO 的查找
join buffer:就是把外表的列放到缓冲区里面,然后直接读取它,而不是每次扫表
的查询。
四、如何知道要优化哪些 SQL 语句?
- 开启慢日志,设置超过几秒为慢的 SQL,抓取慢 SQL 语句
- 根据 Explain 分析语句
五 、创建索引前的注意事项
- 单表索引数量建议不超过 5 个,组合字段也不用超过 5 个字段
- 不建议在更新频繁的字段创建索引
- where 条件不能是表达式的一部分,避免在表达式上进行计算或使用函数
- 如果进行 join 函数,那么被 join 的字段必须类型相同并建立索引,因为 join类型不一致会导致全表扫描
- 隐式类似转换会使索引失效,导致全表扫描
注意! ! !
到这里就完了吗? 并没有,这里只是整理的大纲内容,具体里面每个部分在MySQL的底层工作原理上还未分析,因为篇幅不够,所以我以视频的方式给大家讲解出来了。细讲每个细节,并以工作场景让大家更好的去理解去运用。
需要的同学可关注我,私信:winner-mysql 口令。直接分享给大家