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拆分

相关推荐
xxwl5851 小时前
数据库后端接口测试报告
spring boot·mysql·tomcat
xqqxqxxq1 小时前
MySQL 数据类型笔记
数据库·笔记·mysql
Logintern092 小时前
理解MySQL数据库的“事务与锁”
数据库·mysql
朱容zr3331332 小时前
为什么推荐使用自增主键?使用UUID作为主键的优缺点是什么?
java·运维·数据库·后端·mysql·面试·性能优化
brave_zhao3 小时前
mysql的安装
数据库·mysql
冷凝娇4 小时前
【MySQL】2026总结(一)
数据库·mysql
神龙天舞200115 小时前
MySQL 备库为什么会延迟好几个小时
android·数据库·mysql
每天都要进步哦20 小时前
SQL单行函数详解:字符、数字、日期、转换与通用函数全解析
数据库·mysql
南凉北往21 小时前
PandasAI连接LLM对MySQL数据库进行数据分析
数据库·mysql·数据分析
【心态好不摆烂】1 天前
MySQL——复合查询
数据库·mysql