MySQL 慢查询日志里 rows_examined 比返回行数大三个数量级,问题出在哪

举报
yd_216394844 发表于 2026/10/28 17:02:50 2026/10/28
【摘要】 rows_examined 是优化器实际扫描的行数,返回行数只看结果集大小。两者差三个数量级,说明索引没吃到或者吃错了列,按下面顺序排查。第一步看 EXPLAIN 的 type 和 key。type 是 ALL 说明全表扫,index 说明扫了整棵索引树同样不划算,只有 range、ref、eq_ref 才算用上。key 为 NULL 就是没走索引,重点查 WHERE 列有没有索引、索引列上...

rows_examined 是优化器实际扫描的行数,返回行数只看结果集大小。两者差三个数量级,说明索引没吃到或者吃错了列,按下面顺序排查。

第一步看 EXPLAIN 的 type 和 key。type 是 ALL 说明全表扫,index 说明扫了整棵索引树同样不划算,只有 range、ref、eq_ref 才算用上。key 为 NULL 就是没走索引,重点查 WHERE 列有没有索引、索引列上有没有套函数或隐式类型转换。最典型的是 varchar 列传了数字,MySQL 会做隐式转换,索引直接失效。

第二步看 rows 和 filtered。rows 是预估扫描行数,filtered 是过滤后剩余百分比。预估很小但实际很慢,多半统计信息过期,跑一次 ANALYZE TABLE 再看。

第三步看回表。二级索引查到主键后要回表取其他列,命中行数一多,优化器会干脆放弃索引走全表扫。覆盖索引能省掉回表,把 SELECT 需要的列一起建进索引通常立竿见影。

第四步看 ORDER BY 和 GROUP BY。和索引顺序不一致时会产生 Using filesort 或 Using temporary,扫描量被放大。联合索引的列顺序要和 ORDER BY 对齐,方向也要一致。

最后提醒一个容易误判的情况:LEFT JOIN 右表没索引,或者子查询被改写成半连接,都会让 rows_examined 暴涨,而单看某张表的 EXPLAIN 看不出问题。用 EXPLAIN FORMAT=JSON 看完整执行计划,或者开 optimizer_trace 看优化器怎么选的路,比猜快得多。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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