MySQL执行计划(chatGPT聊天最终获取总结)
                    
                
                
                    一、MySQL 执行计划概述
作用
- 帮助理解优化器如何访问表、使用索引,以及各个操作的成本,定位性能瓶颈。
 
主要列说明
id:查询中各个 SELECT/子查询的序号,越大优先级越高。select_type:查询的类型,如 SIMPLE、PRIMARY、SUBQUERY(子查询)、DERIVED(派生表)等。table:当前行所指的表或临时表。partitions:涉及的分区信息(如果表做了分区)。possible_keys:优化器认为可用的索引列表。key:优化器实际使用的索引。key_len:使用索引的长度(字节数)。ref:哪个列或常数与 key 做对比。rows:优化器估计要读取的行数。type:最重要的访问方式枚举(见下文详解)。Extra:补充信息枚举(见下文详解)。
优化思路
- 减少全表扫描:尽量让 
type值靠前(优先级:ALL最差 →system最好)。 - 合理建索引:针对 
WHERE、JOIN、ORDER BY、GROUP BY设计合适的索引。 - 避免文件排序与临时表:
Extra中出现Using filesort、Using temporary时要警惕。 - 分析并调整 SQL:拆分复杂查询、消除隐式类型转换、避免在索引列上做函数运算等。
 
- 减少全表扫描:尽量让 
 
二、type 列的枚举值(按访问效率从高到低排列)
| 枚举值 | 含义 | 
|---|---|
system | 
表只有一行(等同于常量表),是 const 的特殊情况。 | 
const | 
通过常数(主键或唯一索引)查询出最多一行,速度极快。 | 
eq_ref | 
对于每个外键表的行,使用唯一索引查找主表,最多一行,对应多表 JOIN 时性能好。 | 
ref | 
使用非唯一索引或前缀索引查找,可能匹配多行,通常用于外键关联。 | 
fulltext | 
使用全文索引扫描,适用于 MATCH(...) AGAINST(...) 查询。 | 
ref_or_null | 
类似 ref,但索引列可能为 NULL,匹配时会额外测试 IS NULL。 | 
index_merge | 
合并多个索引的扫描结果(AND 或 OR 条件下),然后合并去重。 | 
unique_subquery | 
内部优化:对子查询(IN (SELECT ...))使用唯一索引。 | 
index_subquery | 
内部优化:对子查询(IN (SELECT ...))使用普通索引。 | 
range | 
对索引的区间扫描,如 >, <, BETWEEN, IN(...) 等操作。 | 
index | 
全索引扫描(相当于全表扫描,但扫描的是索引结构,通常比 ALL 略快)。 | 
all | 
全表扫描,最差的访问方式,读取所有行来检查条件。 | 
说明:
- 优化目标是让访问方式尽量往上靠,如能从
 ALL优化到range、ref、甚至const。- 访问方式越往下,扫描行数越多,查询越慢。
 
三、Extra 列的枚举值
Extra 提供了额外的执行细节,常见枚举包括:
访问与过滤相关
Using where:在存取数据后应用了 WHERE 过滤。Using index:覆盖索引(仅从索引读取数据,无需回表),性能较好。Using index condition:索引条件下推(Index Condition Pushdown, ICP),部分过滤在存取索引时完成。Using join buffer:在某些 JOIN 情况下(如ref无法直接满足)使用 join buffer。
排序与分组相关
Using filesort:需要在 MySQL 层做额外的排序(并非文件写入,仅为命名),会影响性能。Using temporary:使用临时表存放中间结果,常见于GROUP BY、DISTINCT、复杂子查询。
其他
Distinct:在 SELECT DISTINCT 时,对行去重。Impossible WHERE:WHERE 条件永远为假,该部分查询不执行。No tables used:查询不涉及任何表(例如SELECT 1+1)。FirstMatch(table):MySQL 内部优化,找到首个匹配行即可停止扫描。Range checked for each record (index map: ...):对每一行都做一次范围检查(较慢,通常发生在子查询)。Using MRR:多范围读取(Multi-Range Read),将多个范围请求合并、排序后按顺序读取,提升 HDD 性能。Using union(...):内部优化,把多次扫描合并为一次,见index_merge。Using intersection(...):内部优化,多个索引扫描取交集,见index_merge。LooseScan(table):在聚合函数里(如GROUP_CONCAT)做宽松扫描,只取每组的第一行。
小结:
- 出现
 Using filesort、Using temporary、Impossible WHERE时,应重点优化 SQL 或调整索引。- 覆盖索引(
 Using index)和 ICP(Using index condition)是值得追求的优化方向。