【MySQL10】进阶篇 | 索引_#2性能优化

前言

SQL 优化重心:优先优化查询语句 调优排查流程:查看 SQL 执行频次 → 开启慢查询日志捕获慢 SQL → profile 定位耗时阶段 → explain分析执行计划,最后针对性建立索引、改写 SQL。


一、查看 SQL 各类语句执行频率

可以判断数据库业务压力是以查询、新增、更新还是删除为主,查询占比高就重点做查询优化

语法

sql

sql 复制代码
-- session 当前会话级别;global 全局服务器级别
SHOW GLOBAL STATUS LIKE 'Com_____';
  • Com_select:查询次数
  • Com_insert:插入次数
  • Com_update:更新次数
  • Com_delete:删除次数

根据返回数值判断业务模型:

  1. 查询请求居多 → 重心优化 select、建立合适索引
  2. 增删改频繁 → 考虑索引不宜过多、事务优化、分表

二、慢查询日志:抓取执行超时的 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 优化排查流程总结

  1. show global status 判断业务读写比例
  2. 开启慢查询日志,捕获超时慢 SQL
  3. profiling 定位 SQL 内部耗时瓶颈
  4. explain 分析执行计划,观察 type、key、rows
  5. 根据执行计划:新建索引、优化复合索引顺序、改写子查询、避免索引失效语法
相关推荐
C++ 老炮儿的技术栈3 小时前
从 Qt Designer 属性编辑器的层级可以看到继承链
c语言·数据库·c++·qt·sqlite·visual studio
MC皮蛋侠客3 小时前
Redis 系列(一):全景与最小闭环——从 `SET` 命令到内存数据结构
数据结构·数据库·redis
古法安卓4 小时前
Android-深入理解 Android 回调(Callback)机制
android·性能优化·android studio
zt1985q4 小时前
本地部署开源网络书签与内容管理工具 Karakeep 并实现外部访问
运维·服务器·网络·数据库·网络协议·开源
IvorySQL5 小时前
PostgreSQL 日报| PostgreSQL 19 默认 WAL 压缩算法(8 月 8 日)
数据库·postgresql·区块链
油丶酸萝卜别吃6 小时前
MySQL B+ 树查询全过程详解
数据库·mysql
leisoo80976 小时前
股票数据本地化存储实战:JSON、数据库与列式存储的方案对比
jvm·数据库·json
Exclusive_Cat6 小时前
MySQL回表机制解析与优化策略
数据库·sql
Cry丶6 小时前
遗留系统数据迁移实战(九):区域编码迁移与补偿接口设计
mysql·数据治理·数据迁移·区域编码·补偿接口·组织区域