前言
SQL 优化重心:优先优化查询语句 调优排查流程:查看 SQL 执行频次 → 开启慢查询日志捕获慢 SQL → profile 定位耗时阶段 → explain分析执行计划,最后针对性建立索引、改写 SQL。
一、查看 SQL 各类语句执行频率
可以判断数据库业务压力是以查询、新增、更新还是删除为主,查询占比高就重点做查询优化
语法
sql
sql
-- session 当前会话级别;global 全局服务器级别
SHOW GLOBAL STATUS LIKE 'Com_____';
Com_select:查询次数Com_insert:插入次数Com_update:更新次数Com_delete:删除次数
根据返回数值判断业务模型:
- 查询请求居多 → 重心优化 select、建立合适索引
- 增删改频繁 → 考虑索引不宜过多、事务优化、分表
二、慢查询日志:抓取执行超时的 SQL
作用
记录执行耗时超过阈值的 SQL,用来自动捕获线上慢 SQL。
MySQL 默认关闭慢查询日志;默认超时阈值为 10s
1. 查看慢日志开启状态
sql
sql
show variables like 'slow_query_log';
2. 修改 my.cnf 配置(Linux 路径 /etc/my.cnf)
ini
sql
# 开启慢查询日志 1开启 0关闭
slow_query_log = 1
# 慢SQL触发阈值,单位秒,超过2秒就记录
long_query_time = 2
配置完成重启 MySQL 服务生效,之后所有耗时>2s 的 SQL 都会写入慢日志文件。
三、profiling 精准定位 SQL 耗时分布
当 SQL 逻辑简单但是查询耗时很长,使用 profile 查看时间消耗在哪一步
1. 检查数据库是否支持 profile
sql
sql
SELECT @@have_profiling;
2. 开启会话分析
sql
sql
set profiling = 1;
3. 执行业务 SQL
sql
sql
select count(*) from tb_sku;
4. 查看所有已执行 SQL 的耗时列表
sql
sql
show profiles;
5. 查看指定 Query 详细阶段耗时(填入 query_id)
sql
sql
show profile for query 16;
可以看清初始化、索引查找、拷贝数据、排序等每一步耗时。
四、explain /desc 执行计划(SQL 优化最核心工具)
explain用来解析 select 执行方案,查看表连接顺序、索引命中、扫描行数,找到索引失效、全表扫描问题
使用语法
sql
sql
EXPLAIN SELECT 字段列表 FROM 表名 WHERE 查询条件;
--简写
desc select *from tb_user where id = 1;
explain 返回字段详解
1. id
select 查询序列号,代表多表 / 子查询的执行顺序
- id 值不同:数值越大优先执行
- id 值相同:从上往下顺序执行
示例三表联查
sql
sql
explain select s.*, c.*
from student s, course c, student_course sc
where s.id = sc.studentid and c.id = sc.courseid;
子查询案例:查询选修 MySQL 课程的学生
sql
sql
explain select *from student s
where s.id in (
select studentid from student_course sc
where sc.courseid = (
select id from course c where c.name = 'MySQL'
)
);
2. select_type
查询类型,区分普通查询、子查询、关联查询
3. type(最关键!连接匹配类型)
性能从优到劣排序 NULL > system > const > eq_ref > ref > range > index > all
- all:全表扫描,需要优先优化
4. possible_key
本次查询理论上可以用到的候选索引,多个索引都会列出
5. key
查询实际命中、真正使用到的索引,null 代表索引失效、全表扫描
6. key_len
索引使用到的字节长度,可以判断复合索引命中了几个字段
7. rows
InnoDB 预估需要扫描读取的数据行数,数值越小越好
8. filtered
返回有效数据行数 / 扫描读取行数 的百分比
数值越高代表扫描后无效数据越少,查询效率越好
五、整体 SQL 优化排查流程总结
show global status判断业务读写比例- 开启慢查询日志,捕获超时慢 SQL
- profiling 定位 SQL 内部耗时瓶颈
- explain 分析执行计划,观察 type、key、rows
- 根据执行计划:新建索引、优化复合索引顺序、改写子查询、避免索引失效语法