当前位置: 首页 > news >正文

mysql 性能优化之Explain讲解

EXPLAIN是 MySQL 中用于分析查询执行计划的重要工具,通过它可以查看查询如何使用索引、扫描数据的方式以及表连接顺序等信息,从而找出性能瓶颈。以下是关于EXPLAIN的详细介绍和实战指南:

1. EXPLAIN 基本用法

SELECTINSERTUPDATEDELETE语句前加上EXPLAIN关键字即可查看执行计划:

EXPLAIN SELECT * FROM users WHERE age > 18;

2. 关键字段解析

EXPLAIN返回的结果包含多个字段,重点关注以下几个:

id
  • 查询的标识符,数值越大优先级越高,相同数值按顺序执行。
type
  • 数据访问类型,从最优到最差排序:
    • system/const:单条记录查询(主键或唯一索引)。
    • eq_ref:唯一索引扫描(如JOIN操作)。
    • ref:非唯一索引扫描。
    • range:范围扫描(如WHERE age > 18)。
    • index:全索引扫描(仅扫描索引树)。
    • ALL:全表扫描(性能最差)。
possible_keys
  • 可能使用的索引,但不一定实际使用。
key
  • 实际使用的索引,若为NULL则未使用索引。
key_len
  • 索引使用的字节数,用于评估索引的选择性。
rows
  • MySQL 估算的扫描行数,值越小越好。
Extra
  • 额外信息,常见值:
    • Using filesort:需额外排序(性能开销大)。
    • Using temporary:使用临时表(如GROUP BYORDER BY)。
    • Using index:覆盖索引(仅通过索引即可获取所有数据)。

3. 实战优化案例

案例 1:全表扫描优化

问题 SQL

SELECT * FROM orders WHERE status = 'paid';

EXPLAIN 结果

+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table  | type | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
| 1  | SIMPLE      | orders | ALL  | NULL          | NULL | NULL    | NULL | 100000 | Using where |
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+

分析type=ALL(全表扫描),key=NULL(未使用索引)。
优化

ALTER TABLE orders ADD INDEX idx_status (status);

优化后 EXPLAIN

+----+-------------+--------+------+---------------+----------+---------+-------+------+-------------+
| id | select_type | table  | type | possible_keys | key      | key_len | ref   | rows | Extra       |
+----+-------------+--------+------+---------------+----------+---------+-------+------+-------------+
| 1  | SIMPLE      | orders | ref  | idx_status    | idx_status | 152     | const | 500  | Using index |
+----+-------------+--------+------+---------------+----------+---------+-------+------+-------------+

结果type=ref(索引扫描),rows=500(扫描行数大幅减少),Using index(覆盖索引)。

案例 2:复合索引优化

问题 SQL

SELECT user_id, amount FROM orders WHERE user_id = 100 AND status = 'paid';

EXPLAIN 结果

+----+-------------+--------+------+---------------+----------+---------+-------+------+-------------+
| id | select_type | table  | type | possible_keys | key      | key_len | ref   | rows | Extra       |
+----+-------------+--------+------+---------------+----------+---------+-------+------+-------------+
| 1  | SIMPLE      | orders | ref  | idx_user      | idx_user | 4       | const | 1000 | Using where |
+----+-------------+--------+------+---------------+----------+---------+-------+------+-------------+

分析:仅使用了user_id索引,未使用status条件。
优化:创建复合索引:

ALTER TABLE orders ADD INDEX idx_user_status (user_id, status);

优化后 EXPLAIN

+----+-------------+--------+------+-------------------+-------------------+---------+-------------+------+-------------+
| id | select_type | table  | type | possible_keys     | key               | key_len | ref         | rows | Extra       |
+----+-------------+--------+------+-------------------+-------------------+---------+-------------+------+-------------+
| 1  | SIMPLE      | orders | ref  | idx_user_status   | idx_user_status   | 156     | const,const | 50   | Using index |
+----+-------------+--------+------+-------------------+-------------------+---------+-------------+------+-------------+

结果rows=50(扫描行数进一步减少),Using index(覆盖索引)。

案例 3:消除Using filesort

问题 SQL

SELECT * FROM products ORDER BY create_time LIMIT 10;

EXPLAIN 结果

+----+-------------+----------+------+---------------+------+---------+------+--------+----------------+
| id | select_type | table    | type | possible_keys | key  | key_len | ref  | rows   | Extra          |
+----+-------------+----------+------+---------------+------+---------+------+--------+----------------+
| 1  | SIMPLE      | products | ALL  | NULL          | NULL | NULL    | NULL | 100000 | Using filesort |
+----+-------------+----------+------+---------------+------+---------+------+--------+----------------+

分析:全表扫描后进行文件排序(Using filesort)。
优化:添加索引:

ALTER TABLE products ADD INDEX idx_create_time (create_time);

优化后 EXPLAIN

+----+-------------+----------+------+---------------+-------------------+---------+------+------+-------------+
| id | select_type | table    | type | possible_keys | key               | key_len | ref  | rows | Extra       |
+----+-------------+----------+------+---------------+-------------------+---------+------+------+-------------+
| 1  | SIMPLE      | products | index| NULL          | idx_create_time   | 5       | NULL | 10   | Using index |
+----+-------------+----------+------+---------------+-------------------+---------+------+------+-------------+

结果type=index(索引扫描),消除了Using filesort

4. 高级用法:EXPLAIN ANALYZE

MySQL 8.0+ 支持EXPLAIN ANALYZE,返回更详细的执行信息,包括实际扫描行数和时间:

EXPLAIN ANALYZE SELECT * FROM users WHERE age > 18;

5. 优化建议

  1. 优先优化type字段:尽量避免ALLindex类型,目标是ref或更优。
  2. 确保key字段非NULL:通过创建索引让查询使用索引。
  3. 消除Using filesortUsing temporary:通过合理索引避免额外排序和临时表。
  4. 利用覆盖索引:让Extra字段出现Using index,减少回表操作。
  5. 复合索引顺序:将选择性高的字段放在前面(如唯一值多的字段)。

6. 常见误区

  • 索引越多越好:过多索引会增加写操作开销和内存占用。
  • 忽视复合索引顺序:不满足最左匹配原则会导致索引失效。
  • 过度依赖EXPLAIN估算rows是估算值,实际可能有偏差,需结合SHOW PROFILE等工具验证。

通过EXPLAIN深入分析查询执行计划,针对性地优化索引和查询语句,可以显著提升 MySQL 性能。

http://www.dtcms.com/a/285889.html

相关文章:

  • RHEL/CentOS 的系统安装程序界面介绍
  • 周志华《机器学习导论》第9章 聚类
  • 分布式面试点
  • 算法-动态规划
  • MyBatis缓存实战指南:一级与二级缓存的深度解析与性能优化
  • 分布式短剧平台核心技术解析:CDN优化、AI推荐与多语言支付集成
  • 在 ASP.NET Core 和 JavaScript 中配置 WebSocket
  • Jfinal+SQLite处理 sqlite数据库执行FIND_IN_SET报错
  • .NET 8 Release Candidate 1 (RC1)现已发布,包括许多针对ASP.NET Core的重要改进!
  • 从复合变量到分组分析:piecewiseSEM 解析生态系统多因子交互作用
  • 深度剖析:最新发布的ChatGPT Agent 技术架构与应用场景
  • 专题:2025智能体研究报告|附70份报告PDF、原数据表汇总下载
  • NJU 凸优化导论(8) Lagrange Dual 拉格朗日对偶
  • Kotlin集合分组
  • 解决selenium元素定位不到疑难杂症
  • TCL 电视安装 APK 文件主要有 U 盘安装——仙盟创梦IDE
  • nastools继任者?极空间部署影视自动化订阅系统『MediaMaster』
  • echarts dataZoom 文本显示不完整
  • 响应式编程入门教程第六节:进阶?Combine、Merge、SelectMany 与错误处理
  • 【怜渠客】简单实现手机云控Windows电脑锁屏
  • MySQL中的锁有哪些
  • 【软件重构】如何避免意外冗余
  • 一文入门深度学习(以医学图像分割为例)
  • 【机器学习深度学习】LoRA 与 QLoRA:大模型高效微调的进阶指南
  • 【华为机试】70. 爬楼梯
  • 快速安装GitLab指南
  • mix-blend-mode的了解使用
  • git 介绍与使用教程
  • LP-MSPM0G3507学习--05管脚中断
  • 如何 ASP.NET Core 中使用 WebSocket