mysql中like右模糊(如'abc%')可走索引,左模糊('%abc')或全模糊('%abc%')无法利用b+树索引导致全表扫描;必须用explain验证,key为null或type为all即未走索引。

LIKE右模糊能走索引,但左模糊或全模糊直接失效
MySQL 的 LIKE 查询是否走索引,只看通配符位置:只要模式以 % 开头(如 '%abc' 或 '%abc%'),B+ 树索引就无法定位起始位置,只能全表扫描。只有后缀通配符(如 'abc%')才能触发 range 类型的索引扫描。
常见错误现象:EXPLAIN 显示 type = ALL、key = NULL,同时 rows 接近表总行数。
- ✅ 有效写法:
WHERE name LIKE '张%'(走索引) - ❌ 失效写法:
WHERE name LIKE '%张'、WHERE name LIKE '%张%'(不走索引) - ⚠️ 注意:
WHERE name LIKE '张_'(下划线单字符)也走索引,和'张%'同理,因为前缀固定
EXPLAIN 是唯一可信的索引使用判断依据
别猜,直接 EXPLAIN 看执行计划。关键字段就两个:type 和 key。只要 key 是 NULL,或者 type 是 ALL / index,基本可以确认索引没被用上。
使用场景:上线前查慢查询、开发时验证 SQL 是否符合预期、排查线上 LIKE 查询突然变慢。
-
type = range:说明走了索引范围扫描(右模糊典型表现) -
type = ref:说明走了等值索引(如name = '张三') - 如果
Extra出现Using filesort或Using temporary,即使走了索引,也可能因排序/分组引发额外开销
索引列上加函数或运算,等于主动废掉索引
LIKE 本身不“加函数”,但很多人会误套一层函数再查,比如 WHERE UPPER(name) LIKE 'ZHANG%',或者更隐蔽的 WHERE CONCAT('', name) LIKE '张%' —— 这些都会让索引失效,原理和 UPPER()、DATE() 一样:索引存的是原始值,不是计算后的结果。
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
性能影响:小表看不出,大表可能从毫秒级变成秒级甚至分钟级。
- ❌ 错误示例:
WHERE IFNULL(name, '') LIKE '张%'、WHERE TRIM(name) LIKE '张%' - ✅ 替代思路:确保字段本身非空、无前后空格;业务层预处理;或改用生成列 + 索引(MySQL 5.7+)
- ⚠️ 隐式转换也属同类问题:比如
name是VARCHAR,却写成WHERE name = 123,MySQL 会转成WHERE CAST(name AS SIGNED) = 123,同样绕过索引
想搜中间内容?别硬扛 LIKE,换方案
当必须支持 '%关键词%' 场景(如后台管理搜用户名含某字),靠普通 B+ 树索引已无解。强行建索引、调优器参数都收效甚微。
可选路径很明确:要么换索引类型,要么换查询方式。
- ✅ 全文索引(
FULLTEXT):适合中文需分词的长文本,但对短字段(如姓名)效果一般,且 MySQL 内置中文分词弱,常需配合ngram插件 - ✅ 前缀索引 + 应用层兜底:对
name建前缀索引(如INDEX idx_name_4 (name(4))),先快速筛出前 4 字匹配的候选集,再在应用层做二次过滤 - ✅ 倒排结构外置:把姓名切分为所有可能子串(如 “张三” → “张”、“三”、“张三”),存到 Redis 或 Elasticsearch,查得快、扩展性强
真正容易被忽略的是:很多团队花几天调 optimizer_switch 或反复 ANALYZE TABLE,却没意识到问题根本不在优化器——是查询模式和索引机制的天然冲突。接受这个前提,才能跳出去找解法。










