MySQL 索引入门:用 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 看执行计划,按最左前缀原则设计联合索引,再检查是否有导致索引失效的写法。掌握这几步,大部分入门级的数据库性能问题都能自己解决。在云上使用托管数据库时,同样可以借助控制台的慢查询分析功能配合排查。
- 点赞
- 收藏
- 关注作者
评论(0)