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

相关推荐
Dxy12393102161 小时前
三种方式避坑:案例 + 解决方法
python·mysql
暴力求解3 小时前
Mysql数据库基础
数据库·mysql·操作系统
意倾城3 小时前
MySQL最左前缀匹配原则
数据库·mysql
java_cj5 小时前
MySQL 执行原理深度剖析:查询成本计算与优化器内幕
数据库·后端·mysql
Noushiki6 小时前
MySQL索引优化实战:高效查询的黄金法则
数据库·sql·mysql
Dxy12393102166 小时前
Python 操作 MySQL 事务:从入门到避坑
android·python·mysql
爱莉希雅&&&6 小时前
Zabbix监控初步搭建
linux·运维·数据库·mysql·zabbix
狼与自由6 小时前
mysql到clickhouse
数据库·mysql·clickhouse
土狗TuGou6 小时前
SQL内功笔记 · 第6篇:窗口函数的使用ROW_NUMBER等
java·数据库·后端·sql·mysql