mysql如何优化模糊匹配查询_mysqllike索引优化

来源:这里教程网 时间:2026-02-28 20:49:56 作者:

LIKE 查询为什么慢?本质是索引失效

MySQL 的

LIKE
查询在模糊匹配时极易跳过索引,尤其是以通配符开头(如
LIKE '%abc'
)——这时优化器无法使用 B+ 树索引的有序性,只能全表扫描。即使字段上有索引,
EXPLAIN
也会显示
type: ALL
key: NULL

哪些 LIKE 形式能走索引?必须满足左前缀匹配

只有

LIKE 'abc%'
这类「固定前缀 + 后缀通配」才能利用索引的最左前缀原则。注意以下细节:

LIKE 'abc%'
✅ 可用索引(B+ 树从 'abc' 开始向右遍历)
LIKE 'ab%c'
❌ 不可用(中间有通配符,无法确定范围边界)
LIKE '%abc'
❌ 不可用(无确定起始点)
LIKE 'abc\_def'
✅ 可用(
_
是单字符通配,不破坏前缀连续性)
如果字段是
VARCHAR(255)
但实际值平均长度仅 10,建索引时可考虑前缀索引:
INDEX (col_name(10))
,避免索引过大拖慢写入

无法改写为前缀匹配时,替代方案有哪些?

当业务必须支持任意位置匹配(如搜索标题含关键词),硬扛

LIKE '%keyword%'
性能极差,应换思路:

用全文索引:
ALTER TABLE t ADD FULLTEXT(col_name)
,再用
MATCH(col_name) AGAINST('keyword' IN NATURAL LANGUAGE MODE)
—— 支持分词、停用词、相关性排序,但只适用于
MyISAM
InnoDB
(5.6+)
引入外部搜索引擎:Elasticsearch 或 Meilisearch,适合高并发、复杂检索场景;MySQL 仅存原始数据 冗余字段预处理:如提取关键词生成
tags
字段,用
FIND_IN_SET()
或 JSON 匹配,配合普通索引
慎用
REGEXP
:它比
LIKE
更慢,且完全无法用索引

字符集和排序规则对 LIKE 性能有隐性影响

同一查询在不同 collation 下可能走/不走索引。例如:

utf8mb4_unicode_ci
:大小写不敏感,但比较开销大,且某些组合会让优化器放弃索引(尤其涉及函数隐式转换时)
utf8mb4_bin
utf8mb4_0900_as_cs
:二进制或大小写敏感排序,匹配更直接,索引利用率更高
检查字段 collation 是否与查询字面量一致:
SELECT COLLATION(col_name), COLLATION('abc')
;若不一致,MySQL 会隐式转换,导致索引失效
避免在
WHERE
中对字段用函数:
WHERE UPPER(col) LIKE '%ABC%'
→ 索引必然失效
真正卡住性能的往往不是 LIKE 本身,而是没意识到「索引只帮得上左前缀」这个硬约束。一旦需求突破这个边界,就得跳出 SQL 做架构级取舍——要么换存储引擎,要么加搜索中间件,而不是在
LIKE
上反复调参。

相关推荐