一、EXPLAIN 执行计划
1. 基本语法
在 SELECT 语句前添加 EXPLAIN 或 DESC,即可查看 SQL 执行计划:
sql
EXPLAIN SELECT 字段列表 FROM 表名 WHERE 条件;
2. 核心字段含义
表格
| 字段 | 含义 |
|---|---|
| id | 查询序列号,id 相同则从上到下执行;id 不同则值越大越先执行 |
| select_type | 查询类型,如 SIMPLE(简单查询)、PRIMARY(主查询)、UNION(联合查询)等 |
| type | 连接类型,性能从好到差:NULL > system > const > eq_ref > ref > range > index > ALL |
| possible_key | 可能被使用的索引列表 |
| key | 实际使用的索引,为 NULL 表示未使用索引 |
| key_len | 索引使用的最大字节数,越短越好 |
| rows | 预估需要扫描的行数,InnoDB 中为估算值 |
| filtered | 返回行数占读取行数的百分比,值越大越好 |
二、索引使用规则
1. 验证索引效率
通过对比建索引前后的 SQL 耗时,验证索引效果:
-
无索引时执行查询: sql
SELECT * FROM tb_sku WHERE sn = '100000003145001'; -
创建索引: sql
CREATE INDEX idx_sku_sn ON tb_sku(sn); -
再次执行相同查询,对比耗时。
2. 最左前缀法则
联合索引需从最左列开始查询,不能跳过中间列,否则后续列索引失效。
- ✅ 有效:
WHERE profession = '软件工程' AND age = 31 AND status = '0' - ❌ 部分失效:
WHERE age = 31 AND status = '0'(跳过最左列profession)
3. 范围查询
联合索引中若出现 >/< 范围查询,范围查询右侧的列索引将失效。
4. 索引失效场景
- 字符串不加引号:字符串类型字段未加引号,索引失效。
- 头部模糊查询 :
LIKE '%xxx'会导致索引失效;仅尾部模糊LIKE 'xxx%'可使用索引。 - or 连接条件 :
or分割的条件中,若后一列无索引,则所有相关索引都不会被使用。- 示例:
WHERE id = 10 OR age = 23,若age无索引,则id的索引也会失效。
- 示例:
- 索引列运算:在索引列上进行函数 / 算术运算,索引失效。
- 数据分布影响:若 MySQL 评估使用索引比全表扫描更慢,则会选择不使用索引。
三、SQL 性能分析工具
1. 慢查询日志
-
记录执行时间超过
long_query_time(默认 10 秒)的 SQL。 -
配置开启(
/etc/my.cnf):ini
slow_query_log=1 long_query_time=2 -
日志路径:
/var/lib/mysql/localhost-slow.log
2. PROFILE 分析
查看 SQL 执行各阶段耗时:
sql
-- 查看所有 SQL 耗时概况
SHOW PROFILES;
-- 查看指定 query_id 的 SQL 各阶段耗时
SHOW PROFILE FOR QUERY query_id;
-- 查看指定 query_id 的 SQL CPU 使用情况
SHOW PROFILE CPU FOR QUERY query_id;
3. SQL 执行频率统计
统计 INSERT/UPDATE/DELETE/SELECT 执行频次:
sql
SHOW GLOBAL STATUS LIKE 'Com_______';
可查看 Com_select、Com_insert 等操作的累计次数。