所有的 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,心里就踏实了。 这也是中级开发者区别于小白最明显的专业素养之一。

相关推荐
小白勇闯网安圈4 小时前
Django 响应对象、文件上传与类视图
数据库·django·sqlite
努力的小雨5 小时前
同一份 SQL 跑多套环境:Ksql 变量怎么用才安全
数据库
科技绘图5 小时前
快鲸GEO vs 传统AI搜索优化:全链路自动化与高效内容生产在转化闭环上的对比
数据库·人工智能·自动化
ltl6 小时前
数据库作为 LLM 记忆体:语义缓存、RAG 与一致性
数据库
ltl6 小时前
WAL 与崩溃恢复:ARIES 协议怎么跑通
数据库
ltl6 小时前
TEE 数据库:EnclaveDB、Oblivious 原语与机密 SQL
数据库
麻瓜code7 小时前
【Mysql】重新学一遍 SQL 执行顺序
数据库·sql
这个DBA有点耶8 小时前
数据库一体机架构演进:从硬件堆叠到软硬深度耦合
服务器·网络·数据库·硬件架构·运维开发·database·数据库架构
安_9 小时前
RAG的向量数据库:为LLM提供语义搜索能力
数据库
喜欢的名字被抢了9 小时前
程序出问题怎么查,以及如何让它不掉线
java·运维·数据库