MySQL 索引入门:用 EXPLAIN 看懂一条慢查询

举报
yd_256733395 发表于 2026/11/01 14:54:06 2026/11/01
【摘要】 很多应用刚上线时查询飞快,数据量涨到几十万行后,某些页面就开始卡顿。排查下来,大部分情况都和索引有关:要么没建索引,要么建了却没用上。本文用一个简单的订单表,说明怎么用 EXPLAIN 判断查询有没有走索引,以及建索引时几个常见的注意点。一、先看执行计划假设有一张 orders 表,包含 id、user_id、status、created_at 等字段。查询某个用户最近的订单:EXPLAIN...

很多应用刚上线时查询飞快,数据量涨到几十万行后,某些页面就开始卡顿。排查下来,大部分情况都和索引有关:要么没建索引,要么建了却没用上。本文用一个简单的订单表,说明怎么用 EXPLAIN 判断查询有没有走索引,以及建索引时几个常见的注意点。

一、先看执行计划

假设有一张 orders 表,包含 id、user_id、status、created_at 等字段。查询某个用户最近的订单:

EXPLAIN SELECT * FROM orders WHERE user_id = 1001 ORDER BY created_at DESC LIMIT 10;

结果里重点看三列:type 表示访问方式,ALL 代表全表扫描,ref、range 说明用上了索引;key 显示实际使用的索引名,为空就是没用;rows 是预估扫描行数,数字越大越慢。如果看到 type=ALL 且 rows 接近总行数,基本可以确定是缺索引。

二、建一个合适的联合索引

针对上面的查询,可以建立联合索引:

CREATE INDEX idx_user_created ON orders(user_id, created_at);

联合索引遵循“最左前缀”原则:条件里有 user_id 时能用上这个索引,只按 created_at 查询则用不上。把等值条件的列放前面、排序或范围条件的列放后面,通常能让查询同时避免全表扫描和额外排序。再执行一次 EXPLAIN,Extra 列里不再出现 Using filesort,就说明排序也交给了索引。

三、索引失效的常见写法

有了索引也可能用不上,常见原因有:对索引列使用函数,比如 WHERE DATE(created_at) = '2026-11-01',应改写成范围条件;隐式类型转换,比如字符串类型的手机号列用数字去比较;以通配符开头的模糊查询,比如 LIKE '%abc';以及 OR 连接的条件里有一边没有索引。遇到这些情况,优先改写 SQL,而不是盲目再加索引。

四、索引不是越多越好

每个索引都会占用存储空间,并在插入、更新时带来额外维护成本。建议只为高频查询的过滤和排序字段建索引,区分度很低的字段(如只有两三种取值的状态位)单独建索引意义不大。可以定期查看慢查询日志,针对真正拖慢系统的语句优化。

小结

优化查询的基本顺序是:开启慢查询日志找到问题语句,用 EXPLAIN 看执行计划,按最左前缀原则设计联合索引,再检查是否有导致索引失效的写法。掌握这几步,大部分入门级的数据库性能问题都能自己解决。在云上使用托管数据库时,同样可以借助控制台的慢查询分析功能配合排查。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。