EXPLAIN是MySQL提供的查询分析工具,用于显示MySQL如何执行SQL语句,帮助开发者优化查询性能。
sqlEXPLAIN SELECT * FROM table_name WHERE condition;
sqlEXPLAIN FORMAT=JSON SELECT * FROM table_name;
-- 或
EXPLAIN ANALYZE SELECT * FROM table_name;
| 列名 | 说明 | 关键值解读 |
|---|---|---|
| id | 查询标识符 | 数字越大越先执行,相同id按顺序执行 |
| select_type | 查询类型 | 见下方详细说明 |
| table | 访问的表名 | 可能是表名、别名或 |
| partitions | 匹配的分区 | 显示使用的分区 |
| type | 访问类型 | 性能关键指标,见下方说明 |
| possible_keys | 可能使用的索引 | 查询可能使用的索引列表 |
| key | 实际使用的索引 | 实际选择的索引 |
| key_len | 索引长度 | 使用的索引字节数 |
| ref | 索引比较的列 | 显示与索引比较的列或常量 |
| rows | 预估扫描行数 | 估算需要检查的行数 |
| filtered | 过滤百分比 | 存储引擎层过滤后剩余行的百分比 |
| Extra | 额外信息 | 重要优化信息,见下方说明 |
| 类型 | 含义 | 出现场景 |
|---|---|---|
| SIMPLE | 简单查询 | 不包含子查询或UNION |
| PRIMARY | 最外层查询 | 包含子查询的主查询 |
| SUBQUERY | 子查询 | WHERE子句中的子查询 |
| DERIVED | 派生表 | FROM子句中的子查询 |
| UNION | UNION查询 | UNION中的第二个及以后的SELECT |
| UNION RESULT | UNION结果 | UNION的结果集 |
从最优到最差排序:
| 类型 | 描述 | 性能 |
|---|---|---|
| system | 系统表,只有一行 | ⭐⭐⭐⭐⭐ |
| const | 通过主键或唯一索引查询 | ⭐⭐⭐⭐⭐ |
| eq_ref | 关联查询,使用唯一索引 | ⭐⭐⭐⭐⭐ |
| ref | 使用非唯一索引查询 | ⭐⭐⭐⭐ |
| range | 索引范围扫描 | ⭐⭐⭐⭐ |
| index | 索引全扫描 | ⭐⭐⭐ |
| ALL | 全表扫描 | ⭐(需要优化) |
| 信息 | 含义 | 优化建议 |
|---|---|---|
| Using index | 使用覆盖索引 | ✅ 良好 |
| Using where | 使用WHERE过滤 | ⚠️ 可能需要优化 |
| Using temporary | 使用临时表 | 🔴 需要优化 |
| Using filesort | 使用文件排序 | 🔴 需要优化 |
| Using join buffer | 使用连接缓冲 | ⚠️ 可能需要优化 |
sqlEXPLAIN SELECT * FROM users WHERE age > 30 ORDER BY name;
可能的问题输出:
type: ALL (全表扫描)key: NULL (未使用索引)Extra: Using where; Using filesort (WHERE过滤和文件排序)sql-- 添加单列索引
CREATE INDEX idx_age ON users(age);
CREATE INDEX idx_name ON users(name);
-- 添加复合索引
CREATE INDEX idx_age_name ON users(age, name);
sql-- 优化前(可能产生Using filesort)
SELECT * FROM users WHERE age > 30 ORDER BY name;
-- 优化后(使用覆盖索引)
SELECT id, name, age FROM users
WHERE age > 30
ORDER BY name;
确保WHERE条件中的列有索引:
sql-- 不好的写法
SELECT * FROM users WHERE YEAR(create_time) = 2023;
-- 好的写法
SELECT * FROM users WHERE create_time >= '2023-01-01' AND create_time < '2024-01-01';
sql-- 优化前
EXPLAIN SELECT * FROM products WHERE price > 100;
-- 添加索引后
CREATE INDEX idx_price ON products(price);
EXPLAIN SELECT * FROM products WHERE price > 100;
sqlEXPLAIN SELECT u.name, o.order_date
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE u.city = 'Beijing';
优化建议:
users.city上添加索引orders.user_id上添加索引Using temporary和Using filesort| 检查项 | 良好迹象 | 需要优化 |
|---|---|---|
| type | const, ref, range | ALL, index |
| key | 使用索引 | NULL |
| rows | 数值小 | 数值大 |
| Extra | Using index | Using temporary, Using filesort |
通过EXPLAIN分析,可以系统性地识别和解决SQL性能问题,显著提升数据库查询效率。
本文作者:sea-whales
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!