MySQL 慢查询是数据库优化中最常见的问题之一。页面打开慢、接口响应慢、后台列表卡顿,很多时候并不是程序语言本身慢,而是某条 SQL 扫描了太多数据、没有走索引,或者排序和关联方式不合理。
排查慢查询不能只凭感觉改 SQL,也不能看到慢就盲目加索引。更稳妥的流程是:先定位慢 SQL,再用 EXPLAIN 分析执行计划,确认扫描行数、索引使用情况和排序方式,最后再决定是加索引、改 SQL 还是调整业务查询方式。
先定位慢 SQL
排查慢查询的第一步,是找到真正慢的 SQL。可以从应用日志、接口耗时日志、数据库慢查询日志中定位。不要只根据用户说“页面慢”就直接猜是哪张表。
slow_query_log = 1
long_query_time = 1
慢查询日志可以记录超过指定时间的 SQL。线上环境开启前要评估日志量,并做好日志轮转,避免日志文件过大。
看执行计划
找到慢 SQL 后,使用 EXPLAIN 查看执行计划。
EXPLAIN SELECT * FROM orders WHERE user_id = 1001 ORDER BY created_at DESC;
EXPLAIN 能告诉你 MySQL 准备如何执行这条 SQL,包括使用了哪个索引、预计扫描多少行、是否需要额外排序等。

type 字段
type 表示访问类型,常见值包括 ALL、index、range、ref、eq_ref、const 等。一般来说,ALL 表示全表扫描,需要重点关注。
但不是所有 ALL 都一定有问题。如果表很小,全表扫描可能比走索引更快。优化要结合数据量和业务场景判断。
key 和 possible_keys
possible_keys 表示可能使用的索引,key 表示实际使用的索引。如果 possible_keys 有值但 key 为空,说明 MySQL 最终没有使用这些索引。
这时要检查查询条件是否写法不合适,比如字段上用了函数、类型不一致、条件选择性太低,或者索引字段顺序不匹配。
rows 字段
rows 表示 MySQL 预计扫描的行数。这个数字越大,通常查询成本越高。慢查询里如果 rows 非常大,就要重点分析过滤条件和索引。
需要注意 rows 是估算值,不一定完全准确,但足以帮助判断优化方向。
Extra 字段
Extra 会显示额外执行信息。常见内容包括 Using where、Using index、Using filesort、Using temporary。
Using filesort 表示需要额外排序,Using temporary 表示使用临时表。它们不一定绝对有问题,但在大数据量查询中要重点关注。
索引缺失
最常见的慢查询原因是缺少合适索引。比如经常按 user_id 查询订单,却没有给这个字段建索引。
CREATE INDEX idx_user_id ON orders(user_id);
如果查询还会按创建时间排序,可以考虑联合索引。
CREATE INDEX idx_user_created ON orders(user_id, created_at);
联合索引顺序
联合索引字段顺序要匹配真实查询。比如常见条件是按用户筛选,再按时间排序,那么 (user_id, created_at) 通常比 (created_at, user_id) 更合适。
设计联合索引前要看高频 SQL,不要凭字段名字随意组合。
函数导致索引失效
在索引字段上使用函数,可能导致索引无法有效使用。比如按日期查询时写:
WHERE DATE(created_at) = '2026-05-07'
更推荐改成范围查询:
WHERE created_at >= '2026-05-07 00:00:00'
AND created_at < '2026-05-08 00:00:00'
避免 SELECT *
列表页和接口查询不要习惯性写 SELECT *。只查需要的字段,可以减少 IO、网络传输和回表成本。
SELECT id, title, created_at FROM articles WHERE status = 'published';
字段越少,越容易利用覆盖索引。尤其是表里有 TEXT、JSON、大字段时,列表查询更应该明确字段。
分页慢查询
大 offset 分页也常导致慢查询。
SELECT * FROM articles ORDER BY id DESC LIMIT 100000, 20;
可以考虑减少返回字段、延迟关联,或者改用游标分页。
SELECT id, title FROM articles WHERE id < :last_id ORDER BY id DESC LIMIT 20;
关联查询优化
JOIN 慢时,要检查关联字段是否有索引、关联顺序是否合理、过滤条件是否能提前缩小数据范围。
如果关联后数据量很大,可以先筛选出小结果集,再做关联。不要让数据库在大表之间无索引关联。
慢查询不只靠索引
有些慢查询不是简单加索引能解决的。比如一次查询返回几十万行、复杂报表实时计算、模糊搜索前后都有通配符,这些可能需要分页、缓存、异步统计、全文搜索或单独的数据模型。
优化要服务业务,不要让一个页面请求承担过多工作。
常见错误
第一种错误是不看 EXPLAIN,直接加索引。第二种错误是给每个字段都加索引。第三种错误是索引字段上使用函数。第四种错误是列表页 SELECT *。第五种错误是深分页不优化。第六种错误是只关注数据库,不看接口整体耗时。
实践建议
MySQL 慢查询排查可以按这个流程:定位慢 SQL,查看 EXPLAIN,关注 type、key、rows、Extra,确认是否缺索引或索引顺序不对,再考虑 SQL 改写、字段裁剪、分页优化和缓存策略。
慢查询优化不是一次性工作。随着数据量增长,原本很快的 SQL 也可能变慢。保留慢查询日志和定期 review,是数据库长期稳定的基础。













暂无评论内容