所有的 SQL 都要经过 Explain 优化,是什么意思

这句话的意思是:在写完 SQL 语句后,不要想当然地认为它跑得很快,而是要用 EXPLAIN 这个工具去"透视"一下数据库到底是怎么执行这条语句的,确保它走了最优路线(通常是走了索引),而不是在傻傻地全表扫描。

对于刚脱离 CRUD 小白的你来说,这就像是你写完代码不能直接上线,得先看看编译器有没有报错一样。EXPLAIN 就是 MySQL 提供的一个**"体检工具"**,它不会真的去执行你的 SQL,而是返回一个执行计划报告。

🧐 为什么要做 Explain 优化?

假设你写了一条查询:SELECT * FROM users WHERE name = '张三';

  • 你以为的: 数据库像查字典一样,瞬间找到了"张三"。
  • 实际上的: 如果 name 字段没加索引,或者索引失效了,数据库会把整张表几百万行数据从头到尾翻一遍(这叫全表扫描)。平时数据少感觉不出来,一旦上线数据量大了,接口直接卡死。

使用 EXPLAIN 就是在上线前,提前揪出这些性能隐患。

🔍 怎么看 Explain 的结果?(核心看这 4 点)

在你的 SQL 前面加上 EXPLAIN 关键字运行一下(例如:EXPLAIN SELECT * FROM users WHERE name = '张三';),会出来一张表格。作为初学者,你只需要死死盯住下面这 4 个核心字段:

1. type(访问类型)------ 最重要!

这是判断 SQL 好坏的第一标准。它的值代表了 MySQL 查找数据的方式,性能从好到坏的排序大致如下:

  • const / eq_ref:⭐⭐⭐⭐⭐ (完美!通常是通过主键或唯一索引查询,速度极快)
  • ref:⭐⭐⭐⭐ (优秀!使用了普通索引进行等值查询,日常开发追求的目标)
  • range :⭐⭐⭐ (及格!使用了索引进行范围查询,比如 WHERE id > 100
  • ALL :❌ (不及格!全表扫描。意味着数据库把整张表的数据都读了一遍。看到它,就必须想办法优化!)
2. key(实际使用的索引)
  • 如果这一栏显示的是 NULL,说明这次查询没有用到任何索引
  • 如果显示了具体的索引名(比如 idx_name),说明索引生效了。
3. rows(预估扫描的行数)
  • 这个数字代表 MySQL 觉得需要读取多少行才能找到结果。数值越小越好
  • 如果你的表有 10 万行数据,而 rows 显示 9 万,那基本就是在做全表扫描了;如果 rows 是 1 或者几十,说明效率很高。
4. Extra(额外信息)

这里会有一些重要的补充提示,重点关注这两个"坏家伙":

  • Using filesort :意味着 MySQL 需要额外做一次排序操作(非常消耗性能)。通常是因为你的 ORDER BY 字段没有走索引。
  • Using temporary :意味着 MySQL 用了临时表来处理查询(常见于 GROUP BY),这也非常影响性能,需要尽量避免。
  • 如果是 Using index:那是极好的,说明用到了"覆盖索引",连回表查数据的步骤都省了。

💡 举个实战例子

假设你有一张订单表 orders,里面有 100 万条数据。

你写了一条 SQL:SELECT * FROM orders WHERE order_no = 'DD123456';

  • 情况一(未优化):

    你运行 EXPLAIN 后发现:typeALLkeyNULLrows1000000

    👉 结论: 完蛋,它在遍历 100 万行数据找这一个订单。赶紧给 order_no 字段加个索引!

  • 情况二(优化后):

    加了索引后,再次运行 EXPLAINtype 变成了 refkey 显示 idx_order_norows 变成了 1

    👉 结论: 完美!数据库通过索引一步到位找到了这行数据。

总结一下:

所谓"所有的 SQL 都要经过 Explain 优化",就是让你养成一个好习惯------写完稍微复杂一点或者用在核心业务上的 SQL,随手在前面加个 EXPLAIN 跑一下,只要看到 type 不是 ALL,心里就踏实了。 这也是中级开发者区别于小白最明显的专业素养之一。

相关推荐
cui_ruicheng8 小时前
MySQL(四):数据类型与字段设计
数据库·mysql
皮皮学姐分享-ppx9 小时前
政府绿色采购数据库(2015-2024.3)
大数据·网络·数据库·人工智能·制造
闪电悠米11 小时前
黑马点评-Redis 消息队列-03_stream_consumer_group
开发语言·数据库·redis·分布式·缓存·junit·lua
DIY源码阁11 小时前
JavaSwing航班订票管理系统 - MySQL版
数据库·mysql
浪客灿心12 小时前
项目篇:模块设计与实现
数据库·c++
流星白龙14 小时前
【MySQL高阶】26.事务(1)
数据库·mysql
三十..14 小时前
Redis 核心原理与高可用架构实践
运维·数据库·redis
这个DBA有点耶15 小时前
索引优化深潜(下):索引合并、ICP 与索引设计的实战法则
数据库·mysql·架构
努力努力再努力wz15 小时前
【内存管理与高并发内存池系列】从 mmap 到 malloc:文件映射、匿名映射与 glibc 内存分配机制详解
linux·c语言·数据结构·数据库·c++·qt·链表
Theo·Chan15 小时前
机房断电搞崩服务器 | 人大金仓 V8 全量备份跨实例完整恢复实录
sql·信创·kingbase·金仓