mysql like查询怎么走索引_mysql模糊查询优化方法

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

LIKE 查询能走索引吗?取决于通配符位置

能,但仅当通配符不在最左侧时。MySQL 的 B+ 树索引是按字典序存储的,

LIKE 'abc%'
可以利用索引前缀匹配快速定位起始位置;而
LIKE '%abc'
LIKE '%abc%'
无法确定索引扫描起点,只能全表扫描。

常见错误现象:

EXPLAIN
显示
type=ALL
key=NULL
,即使字段有索引也无效。

LIKE 'abc%'
→ 可走索引(range 类型)
LIKE 'ab%c'
→ 部分走索引(只匹配到
'ab'
前缀,后续字符需回表过滤)
LIKE '%abc'
LIKE '%abc%'
→ 不走索引(除非用全文索引或倒排)

用 FULLTEXT 替代 %LIKE% 的模糊搜索

当必须支持任意位置匹配(如搜索“数据库优化”中的“优化”),又想避免全表扫描,

FULLTEXT
是更合适的选择,尤其适用于中文需配合
ngram
分词器。

使用前提:表引擎为

InnoDB
MyISAM
,字段类型为
CHAR
/
VARCHAR
/
TEXT
,且已建立全文索引。

ALTER TABLE articles ADD FULLTEXT(title, content);
SELECT * FROM articles WHERE MATCH(title, content) AGAINST('优化' IN NATURAL LANGUAGE MODE);

注意:

AGAINST()
不支持通配符组合,
'优*'
仅在布尔模式生效,且最小词长默认为 4(中文需调
innodb_ft_min_token_size
或用
ngram
)。

前导通配符场景下,考虑生成反向索引列

若业务强依赖

LIKE '%abc'
(如查“手机号末四位”),可新增一个
REVERSE(phone)
列并建索引,把后缀查询转为前缀查询。

操作步骤:

添加计算列:
ALTER TABLE users ADD COLUMN phone_rev VARCHAR(20) STORED AS (REVERSE(phone));
建索引:
CREATE INDEX idx_phone_rev ON users(phone_rev);
改写查询:
WHERE phone_rev LIKE REVERSE('1234') + '%'
→ 实际执行
WHERE phone_rev LIKE '4321%'

该方案对写入有轻微开销(计算列需维护),但能稳定走索引;注意

REVERSE()
对中文 UTF8MB4 字符安全,但不适用于含 emoji 等四字节字符的混合场景。

LIKE 查询性能差?先确认是否真的需要模糊匹配

很多所谓“模糊需求”其实可通过结构化方式规避:比如地址拆成

province
/
city
/
district
字段,用等值或范围查询;用户昵称搜索可结合拼音首字母索引 + 全文索引兜底。

容易被忽略的关键点:

索引长度限制:
VARCHAR(255)
字段建了索引,但
LIKE 'a%' AND LENGTH(col) > 100
仍可能因索引未覆盖足够长度而失效
字符集影响:
utf8mb4_unicode_ci
utf8mb4_general_ci
在排序和比较行为上不同,可能导致预期外的索引跳过
隐式类型转换:
WHERE name LIKE 123
会触发
name
列隐式转数字,索引完全失效

相关推荐