引言

在MySQL性能优化中,执行计划(Execution Plan)是开发者手中的"X光机"。本文将通过原理剖析、字段解析和实战案例,系统解读这个DBA必备的调优工具。

一、执行计划的核心定义

MySQL执行计划是查询优化器根据统计信息生成的查询执行路径图,通过EXPLAIN命令输出,展示以下关键信息:

  • 数据访问方式(全表扫描/索引扫描)
  • 表连接顺序与类型
  • 临时表使用情况
  • 排序操作实现方式

二、如何获取执行计划

2.1 基础命令

EXPLAIN SELECT * FROM users WHERE age > 18;

2.2 增强版(MySQL 8.0+)

EXPLAIN ANALYZE SELECT * FROM users WHERE age > 18;
-- 实际执行并显示耗时

三、执行计划关键字段详解

3.1 核心字段矩阵

字段 含义 示例值
id 查询块编号(子查询/UNION时递增) 1
select_type 查询类型(SIMPLE/PRIMARY/SUBQUERY/UNION等) SIMPLE
table 当前操作的表名(可能显示衍生表或临时表) users
partitions 命中的分区(分表场景) p0,p1
type 连接类型(决定性能的关键指标) ref
possible_keys 可能用到的索引 idx_age
key 实际使用的索引 idx_age
key_len 索引使用长度(判断复合索引使用情况) 4
ref 与索引比较的列或常量 const
rows 预估扫描的行数(越小越好) 100
filtered 按条件过滤后的行百分比 10.0
Extra 额外信息(重要提示区) Using index condition

3.2 关键字段深度解析

(1) type字段详解(从最优到最差)
  • system:表只有一行(系统表)
  • const:通过索引一次找到(主键/唯一索引)
  • eq_ref:连接时使用主键/唯一索引
  • ref:非唯一索引查找
  • range:范围扫描(BETWEEN/IN/>)
  • index:全索引扫描(覆盖索引)
  • ALL:全表扫描(最差)

示例

EXPLAIN SELECT * FROM users WHERE id = 100; 
-- type=const(最佳)

EXPLAIN SELECT * FROM users WHERE age > 18; 
-- type=range(可接受)

EXPLAIN SELECT * FROM users; 
-- type=ALL(需优化)
(2) Extra字段重要提示
  • Using index:覆盖索引(最佳)
  • Using where:需要回表查询(可能存在索引失效)
  • Using temporary:使用临时表(需警惕)
  • Using filesort:文件排序(性能瓶颈)
  • Impossible WHERE:条件矛盾(如age=18 AND age=20)

四、执行计划实战分析

4.1 典型优化案例

原始查询(未优化)

EXPLAIN SELECT * FROM orders 
JOIN users ON orders.user_id = users.id 
WHERE users.age > 18 AND orders.status = 'completed'

执行计划分析

id | select_type | table | type  | possible_keys          | key         | rows | Extra
---|-------------|-------|-------|------------------------|-------------|------|------------------
1  | SIMPLE      | users | range | idx_age,idx_user_pk   | idx_age     | 5000 | Using where
1  | SIMPLE      | orders| ref   | idx_status,idx_user_id | idx_user_id | 10   | Using index

优化建议

  1. 为orders表增加复合索引idx_status_user_id(status,user_id)
  2. 调整查询顺序,优先过滤status字段
  3. 使用覆盖索引避免回表

4.2 索引失效典型场景

问题查询

EXPLAIN SELECT * FROM users 
WHERE DATE(create_time) = '2025-09-01'

执行计划

type=ALL, Extra=Using where

原因:对索引列使用函数导致失效

优化方案

-- 改写为范围查询
SELECT * FROM users 
WHERE create_time >= '2025-09-01 00:00:00' 
  AND create_time < '2025-09-02 00:00:00'

五、执行计划优化原则

5.1 黄金三法则

  1. 减少扫描行数:优先使用索引扫描(type=ref/range)
  2. 避免临时表:警惕Extra中的Using temporary
  3. 消除文件排序:优化ORDER BY子句

5.2 索引优化策略

  • 复合索引顺序:将过滤条件列放在联合索引左侧
  • 覆盖索引:SELECT字段包含在索引中
  • 索引下推:启用索引条件下推(ICP)
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐