写在开始 : 本篇博客仅仅用作个人知识点复习用~
1. MySQL优化
1. 1 定位慢查询
- 当时做压测的时候有的接口非常慢,响应时间在2s以上,然后系统有部署运维的监控系统 Skywalking,在展示的报表可以定位到哪个接口比较慢,也可以分析这个接口哪部分比较慢,能看到SQL的具体执行时间,就可以定位哪个sql出问题;
- 假如项目没有类似的运维监控系统,在MySQL里也有慢日志查询功能,首先在 MySQL 的系统配置文件开启这个慢日志功能,也可以设置 SQL 执行超过多少时间来记录到一个日志文件,比如配置2s,只要sql执行时间超过2s就会被记录到日志文件中,那就可以在日志文件找到执行慢的SQL了;
**可能原因 : **
- 聚合查询 ->新增临时表解决 —>SQL执行计划(找到慢的原因)
- 多表查询 ->优化SQL语句结构 —>SQL执行计划(找到慢的原因)
- 表数据量过大查询 -> 添加索引 —>SQL执行计划(找到慢的原因)
- 深度分页查询 ->覆盖索引
覆盖索引指查询使用索引,返回的列,必须在索引中全部能找到
使用id查询,直接走聚集,一次索引扫描,直接返回数据,性能高;
如果返回的列没有建索引,可能触发回表查询,尽量避免用 Select *;
:::info
Q : 数据量大时,limit分页查询,需要对数据排序,效率低(超大分页如何处理)
A : 覆盖索引 + 子查询
:::
:::info
覆盖索引,最左匹配原则时优化查询的常见思路
最左匹配:先匹配最左边的,索引只能⽤于查找key是否存在(相等),遇到范围查询 (>、<、between、like左匹配)等就不能进⼀步匹配了,后续退化为线性查找
从最左边为起点开始连续匹配,遇到范围查询终止;
:::
-- 先分页查询数据的 id 字段,确定id 后,再用子查询过滤,只查询这个 id 列表的数据就可以,因为
-- 查询 id 时候,走覆盖索引,所以效率可以提升很多
select * from t_sku limit 0,10; (0.00sec)
select * from t_sku limit 9000000,10; ( 11.05sec)
-- 优化 :
select * from t_sku t,(select id from t_sku order by id limit 9000000,10) a
where t.id = a.id;
表象 ; 页面加载慢,接口压测响应时间长( 超过 1 s )
**工具 : **
- 阿尔萨斯 调试工具
- 运维工具 : 普罗米修斯 Skywalking
MySQL自带慢日志
MySQL 定位慢查询的步骤如下:
开启查询日志,在
my.cnf
配置文件中将slow_query_log
参数设置为ON
,并设置slow_query_log_file
指定日志文件的路径。设置慢查询阈值,在
my.cnf
配置文件中将long_query_time
参数设置为一个较小的值,通常为2秒到5秒,以便记录数据库查询速度慢的SQL语句。重启 MySQL 服务,以使配置文件的修改生效。
分析查询日志文件,查看哪些 SQL 语句运行时间较长;可以使用
mysqldumpslow
工具快速统计查询日志。