HelloCoder HelloCoder
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
  • 《可观测和监控》
  • 《k8s学习心得》
随笔
关于作者
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
  • 《可观测和监控》
  • 《k8s学习心得》
随笔
关于作者
  • 《LearnJavaToFindAJob》

    • 导读

    • 【初级】6~12k档

    • 【中级】12k-26k档

      • JVM进阶

      • Java进阶

      • MySQL

        • Innodb和MyISAM索引的区别
        • MySQL-like是否可以使用索引
        • MySQL一些索引失效的场景和原理
        • MySQL大表索引重建
        • MySQL如何行转列?
        • MySQL死锁的场景
        • MySQL的架构和执行流程
        • MySQL的缓存
        • MySQL的自增ID用完了会怎样?
        • MySQL索引的分类、何时使用、何时不使用、何时失效?
        • MySQL联合索引在B+数的存储结构和最左匹配原则原理
        • MySQL连表优化
        • MySQL连表查询的原理
        • MySQL那种事务隔离级别性能高
        • Mysql的索引和主键的区别
        • binlog、redolog、undolog的区别和作用
        • 什么是前缀索引,什么情况才使用?
        • 可重复读是否能解决幻读?
        • 我以为我对Mysql事务很熟,直到我遇到了阿里面试官
        • 聊聊MySQL索引的分类和结构吧
        • 脏读、幻读
      • 中间件

      • 算法

      • 高阶

    • 【高级】26k+档

    • 大厂面试题

    • 求职建议

    • 面经

  • LearnJavaToFindAJob
  • 【中级】12k-26k档
  • MySQL
#MySQL-like
HaC
2026-06-25
目录

MySQL-like是否可以使用索引

如果你读了这篇文章 Innodb和MyISAM索引的区别 ,你了解索引的结构后,就很容易明白了。

简单直接的回答:可以使用索引,但有一个非常著名的“最左前缀”限制。俗称:左模糊('%a')走不了索引,右模糊('a%')可以走索引。

如果是中间 '%a%',触发覆盖索引,即列刚好就是索引列本身,就能走索引,否则不行。

# 一、 核心匹配原理:为什么“左模糊”不行,“右模糊”可以?

MySQL 的默认索引是 B+ 树索引,它是严格按照从左到右的顺序对字符进行排序的。

假设我们对 name 字段建了索引,索引树里排好序的数据长这样:

apple` ——> `banana` ——> `cat` ——> `dog`

# 1. 右模糊:LIKE 'a%'(走索引:Range Scan)

  • SQL 示例:SELECT * FROM users WHERE name LIKE 'a%';
  • 底层匹配过程:MySQL 拿着英文字母 a 去 B+ 树里找。因为树是排好序的,它能瞬间定位到以 a 开头的第一个单词(apple),然后顺着链表往后读,直到遇到不是 a 开头的单词为止。
  • 结果:成功触发索引范围扫描,效率很高。

# 2. 左模糊:LIKE '%a'(不走索引:Full Table Scan)

  • SQL 示例:SELECT * FROM users WHERE name LIKE '%a';
  • 底层匹配过程:你想找以 a 结尾的单词。但在 B+ 树里,数据是按开头字母排序的(apple、banana 在不同分支)。对于以什么结尾,整棵树是完全无序的。
  • 结果:MySQL 无法在树分支里做二分查找,只能被迫放弃索引,进行全表扫描(Full Table Scan)。

# 3. 双模糊:LIKE '%a%'(不走索引)

  • 道理同上,开头字母不确定,B+ 树直接瘫痪,只能全表扫描。

# 二、 实战特例:两招让“左/双模糊”也能走索引

在实际生产中,如果业务逼得你非要用 LIKE '%a' 或 LIKE '%a%',有以下两个经典的调优方案:

# 1. 覆盖索引(Index Coverage)—— 绕过全表扫描

如果你的查询语句里,SELECT 的列刚好就是索引列本身,哪怕你写 LIKE '%a%',它也会走索引。

  • 例子:

    -- 假设 name 字段有索引
    SELECT name FROM users WHERE name LIKE '%a%';
    
  • 为什么能走索引? 因为索引树本身就包含了 name 字段的完整数据,而且索引树的体积远比存放整行数据的“聚簇索引(表本身)”小得多。MySQL 优化器一看:“反正都要全扫描,那我直接去扫描体积更小的 name 索引树好了。” 在 EXPLAIN 里你会看到 type 是 index(索引全扫描),虽然比不上 range,但比全表扫描(ALL)快得多。

# 2. 虚拟列 + 倒序索引(Reverse Index)—— 解决左模糊的奇招

如果你要频繁查手机号后四位(LIKE '%1234')或者 域名呢?。

  • 绝招:在数据库里多存一个字段 name_reversed,把字符串倒过来存(比如 apple 存成 elppa)。然后对这个倒序字段建索引。
  • 改写查询:把 LIKE '%1234' 改写为针对倒序字段的右模糊查询:LIKE '4321%'。
  • 结果:成功完美压榨 B+ 树索引!

# 三、总结

LIKE 表达式 能否走索引 索引类型 (type) 底层原理
LIKE 'abc%' 能 range 匹配前缀,利用 B+ 树有序性直接定位
LIKE '%abc' 不能 ALL (除非触发覆盖索引) 尾部无序,被迫全表扫描
LIKE '%abc%' 不能 ALL (除非触发覆盖索引) 中间无序,被迫全表扫描
LIKE 'ab_c%' 能 range 前两个字符固定,依然能利用前缀定位
#MySQL-like
上次更新: 2026-06-25 17:18:05
最近更新
01
MySQL支持的锁有哪些
06-25
02
HTTP 是不保存状态的协议, 如何保存用户状态
06-25
03
WebSocket、短轮询、长轮询的区别
06-25
更多文章>
Theme by Vdoing | Copyright © 2020-2026 HaC
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式