MySQL 索引明明在却走了全表:一次隐式类型转换的排查

举报
yd_228518794 发表于 2026/11/01 05:33:57 2026/11/01
【摘要】 一条主键查询突然慢了 600 倍,索引在却没用上。用 EXPLAIN 定位到隐式类型转换,顺手整理了几种常见的索引失效场景。

一条按主键查的 SQL,平时 2ms,某天突然变成 1.2 秒。看 SQL 本身没改,索引也在,最后发现是传参类型不对,触发了隐式转换。

一、先用 EXPLAIN 看真实执行计划

EXPLAIN SELECT * FROM orders WHERE order_no = 20241101001;

如果 type 是 ALL、rows 接近全表、key 为 NULL,说明索引没走。明明 order_no 上有索引,为什么不用?

二、隐式转换会让索引失效

order_no 是 varchar,但传进来的是数字。MySQL 会按「字符串转数字」的规则比较,等价于对字段做了函数运算,索引直接作废。

-- 失效
WHERE order_no = 20241101001
-- 生效
WHERE order_no = '20241101001'

反过来,字段是 int 而传字符串 '123',是可以走索引的,因为转换发生在常量侧。这一点常被记反。

三、怎么系统性找出来

  1. 打开慢查询日志:slow_query_log=ON,long_query_time=0.5。
  2. 用 pt-query-digest 汇总,按 Rows_examined 排序。
  3. 对 Top SQL 逐条 EXPLAIN,重点看 type 与 key。

四、还有几种同类陷阱

  • 字段上做运算:WHERE DATE(create_time) = '2024-11-01',改成范围查询。
  • 前导通配:LIKE '%abc',索引无能为力。
  • 联合索引不满足最左前缀。
  • 字符集不一致的 JOIN,同样触发转换。

结论:索引没走,先怀疑类型和函数,而不是先去加索引。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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