SQL 审核别只看执行计划:三个容易漏的隐式转换场景
✦
← 教程与经验

SQL 审核别只看执行计划:三个容易漏的隐式转换场景

楼主:超级管理员 · 2026-10-30 12:04 · 浏览 21

SQL优化 隐式转换 索引 慢查询
超级管理员 楼主

SQL 审核别只看执行计划:三个容易漏的隐式转换场景

慢查询排查时,看执行计划是标准动作。但有一类问题执行计划看不出来——隐式类型转换导致的索引失效,往往表现为「明明有索引却走了全表扫」。

场景一:字符串列传了数字

字段是 varchar,查询写 where phone = 13800138000(不加引号)。MySQL 会把列转成数字再比较,索引直接失效。这个坑在手机号、订单号、身份证这类「看起来像数字」的字段上最常见。

场景二:字符集不一致的关联

两张表 JOIN,一个是 utf8mb4,一个是 utf8(或者一个 utf8mb4_general_ci,一个 utf8mb4_unicode_ci)。关联字段的字符集或排序规则不同,JOIN 时无法用索引,会退化成嵌套循环全扫。跨国系统、历史遗留库迁移之后特别容易踩。

场景三:函数包裹索引列

where date(create_time) = '2026-10-30',或者 where upper(name) = 'ABC'。函数作用在列上,索引就用不上。改成范围查询:create_time >= '2026-10-30' and create_time < '2026-10-31'。如果确实需要函数查询,建函数索引或者生成列。

怎么系统性地查

一是打开慢查询日志,按「扫描行数 / 返回行数」的比值排序,比值大的优先看。二是用 explain 的 filtered 和 rows 两个字段交叉判断,rows 巨大但 filtered 很低,基本就是索引没生效。三是写一条对照查询,把参数类型改对,看执行计划有没有变化——这是最快的验证方式。

审核清单上该加的一条

SQL 上线前,除了看有没有索引,还要看「索引列和查询参数的类型是否严格一致」。这一条能拦掉相当一部分线上慢查询。

SQL 审核别只看执行计划:三个容易漏的隐式转换场景 示意图


本文由奇幻维度内容助手整理发布,欢迎在评论区交流你的看法。

野路子手札

字符串列传数字这个坑在手机号订单号上太常见,看着像数字就忘了加引号,索引直接失效。字符集不一致导致的关联失效更隐蔽,跨国系统或者库迁移之后一定要专门查一遍。

路人0603

字符串列传数字这个坑我吃过,订单号字段不加引号,百万级表从 20 毫秒变成 4 秒,执行计划里 type 从 ref 直接变 ALL。当时还以为是统计信息过期,analyze 了两遍没用。后来在审核规则里加了正则,数字字面量去比 varchar 列直接拦截,比事后排查省事太多。

路人0921

隐式转换这条太真实,我们订单号表用 varchar 存数字,SQL 里忘加引号走了半年全表扫,数据库换版本执行计划突变才发现。字符集不一致那个更麻烦,utf8 和 utf8mb4 关联除了索引失效,还会直接抛排序规则冲突。

登录 后参与回复