MySQL 四大索引失效写法 + 业务替代最优解决方案

核心原则:不是不让你做这个功能,是不让你用「导致索引失效的SQL语法」去做 。 所有模糊、匹配、时间筛选、多值查询都有高性能替代方案,下面逐个对应业务场景给出可直接上线的写法。

目录

[一、左模糊/全模糊查询 LIKE '%xxx' / '%xxx%'](#一、左模糊/全模糊查询 LIKE '%xxx' / '%xxx%')

[1. 为什么不推荐?](#1. 为什么不推荐?)

[2. 业务想实现模糊搜索怎么办?(3种正规方案)](#2. 业务想实现模糊搜索怎么办?(3种正规方案))

[二、字段隐式类型转换(字符串=数字 / 数字=字符串)](#二、字段隐式类型转换(字符串=数字 / 数字=字符串))

[1. 为什么失效?](#1. 为什么失效?)

[2. 正确写法(一秒修复)](#2. 正确写法(一秒修复))

三、索引字段用函数/运算:DATE()、+、-、OR、SUBSTR

[1. 典型烂写法(失效)](#1. 典型烂写法(失效))

[2. 问题本质](#2. 问题本质)

[3. 业务替代最优写法(功能一模一样、索引生效)](#3. 业务替代最优写法(功能一模一样、索引生效))

[四、OR 乱使用 + IN 超大集合](#四、OR 乱使用 + IN 超大集合)

[1. OR 失效解决](#1. OR 失效解决)

[2. IN 超大集合解决(in(1,2,3...10000))](#2. IN 超大集合解决(in(1,2,3...10000)))

五、终极口诀(面试必背、开发必守)


一、左模糊/全模糊查询 LIKE '%xxx' / '%xxx%'

1. 为什么不推荐?

B+树索引是前缀有序,后缀、全文无顺序,无法走索引,直接全表扫描,大表直接超时。

2. 业务想实现模糊搜索怎么办?(3种正规方案)

方案1:能右模糊就全部用右模糊(优先首选)

需求:搜以"华为"开头的商品 正确写法:LIKE '华为%'可以走索引

方案2:必须全模糊/后缀模糊(商品名称、标题搜索)

绝对不要用数据库! 线上标准做法:用 ES / Elasticsearch / Solr 做全文检索,数据库只存原始数据,不扛搜索。

方案3:小表临时兜底

数据量很小(万级以内)可临时用,大表一律上ES。


二、字段隐式类型转换(字符串=数字 / 数字=字符串)

1. 为什么失效?

规则:字段类型被转换,索引失效 例:phone 是字符串索引,你写 where phone=13800001111 MySQL 内部等价于:where CAST(phone AS unsigned)=13800001111 索引字段被函数包裹 → 索引报废。

2. 正确写法(一秒修复)

永远保持两边类型一致

字符串字段 → 加引号:where phone='13800001111'

数字字段 → 不加引号

结论:功能完全不变,但是索引直接生效


三、索引字段用函数/运算:DATE()、+、-、OR、SUBSTR

1. 典型烂写法(失效)

where DATE(create_time) = '2026-05-28'

where user_id + 1 = 1002

2. 问题本质

索引字段被包裹运算 → 无法走B+树有序索引

3. 业务替代最优写法(功能一模一样、索引生效)

时间匹配替代方案(高频)

淘汰:DATE(create_time) = '2026-05-28'

最优:create_time >= '2026-05-28 00:00:00' AND create_time < '2026-05-29 00:00:00'

范围查询替代函数,完美走索引

字段运算替代方案

淘汰:user_id + 1 = 1002

最优:user_id = 1001把运算丢给参数,不丢给字段


四、OR 乱使用 + IN 超大集合

1. OR 失效解决

烂写法:where user_id=1001 or status=1(status无索引)

问题:or 只要有一个无索引字段,整句索引失效

替代方案:拆分 UNION ALL

把两个条件拆成两条单查再合并,各自走各自索引,性能翻倍。

2. IN 超大集合解决(in(1,2,3...10000))

问题:IN 数量过大,MySQL优化器放弃索引走全表扫描

业务解决方案:

1)IN 数量控制在 500~1000 以内

2)超大批量匹配 →临时表/关联JOIN查询

3)批量数据优先走缓存、批量SQL,避免超大IN


五、终极口诀

  1. 字段不动、参数动(永远不对索引字段做函数、运算)

  2. 能右模糊绝不左模糊,全模糊交给ES

  3. 类型严格对齐,杜绝隐式转换

  4. 大IN拆分、烂OR拆分

相关推荐
CoderMeijun2 小时前
一条SQL查询语句在MySQL中是如何执行的
mysql·sql执行流程·连接器·mysql架构·索引下推·执行器
ttwuai7 小时前
GoFrame 连接 MySQL 报错排查:parseTime、时区和 utf8mb4 怎么配
数据库·mysql·adb
辉灰笔记7 小时前
MySQL8 意外关机/误移data目录导致服务启动失败 PID报错/权限报错 修复文档
linux·数据库·mysql·centos
喜欢的名字被抢了8 小时前
MySQL核心机制:事务、锁与存储引擎
数据库·sql·mysql·教程
消失的旧时光-19439 小时前
MySQL 索引原理系列(二·补充):MySQL 为什么不用红黑树,而用 B+树?
数据库·b树·mysql·红黑树
万亿少女的梦16810 小时前
基于Spring Boot、Vue.js和MySQL的超市管理系统设计与实现
java·vue.js·spring boot·mysql·管理系统
weixin_3077791310 小时前
Linux下Docker Compose里运行的MySQL数据库故障诊断Shell脚本
linux·运维·mysql·docker·自动化
辉灰笔记12 小时前
第一篇:MySQL8.0生产备份实战|XtraBackup全自动全量+增量备份(钉钉告警+异地Binlog归档)
数据库·mysql·钉钉·运维开发
wzy062313 小时前
VIP + Orchestrator + 自定义脚本 MySQL 高可用方案
mysql·orchestrator
TPBoreas1 天前
MySQL性能优化面试全攻略
mysql·面试·性能优化