like '%abc'一定慢是因为b+树索引按字典序从左到右组织,无法反向定位后缀,即使有索引也触发全表扫描;仅like 'abc%'等前缀匹配可走索引,且需满足索引存在、选择性高、无函数干扰等前提。

直接说结论:LIKE不是万能的模糊搜索工具,LIKE '%关键词%'在百万级以上数据表中基本等于拒绝响应——它不慢,是根本没得优化。
LIKE '%abc' 后缀匹配为什么一定慢?
因为B+Tree索引按字符串字典序从左到右组织,数据库无法从末尾反向跳查。哪怕你给name字段加了INDEX(name),WHERE name LIKE '%abc'依然触发全表扫描。
- MySQL 8.0+ 可建函数索引:
CREATE INDEX idx_name_rev ON t((REVERSE(name))),查询改写为WHERE REVERSE(name) LIKE REVERSE('abc') || '%' - 低版本 MySQL 或 PostgreSQL 需显式添加反向列:
ALTER TABLE t ADD COLUMN name_rev VARCHAR(255) AS (REVERSE(name)) STORED,再对name_rev建普通索引 - 别用
SUBSTR(name, -3) = 'abc'——函数作用于字段会让所有索引失效
LIKE 'abc%' 前缀匹配真能走索引?
能,但有前提:索引必须存在,且优化器真信这个条件有足够选择性。如果name LIKE 'A%'命中 80% 的行,优化器大概率弃索引选全表扫描。
- 用
EXPLAIN确认执行计划:type为range、key显示索引名、rows远小于总行数才算有效 - 前缀越长,选择性越好。比如
LIKE 'ZhangLiu%'比LIKE 'Z%'更可能走索引 - 避免在存储过程中拼成
CONCAT('%', @kw)或REPLACE(@kw, '_', '\_') ESCAPE '\'——这类动态拼接常让优化器放弃索引
中文和特殊字符怎么不出错?
同一个LIKE '张%'在utf8mb4_general_ci和utf8mb4_0900_as_cs下可能返回完全不同结果;搜字符串'10%'不加转义就变成“任意长度数字后跟%”。
- 查字段排序规则:
SHOW FULL COLUMNS FROM users LIKE 'name',确认Collation是否支持你要的匹配语义 - 搜实际含
%或_的内容,必须用ESCAPE:WHERE comment LIKE '%10!%' ESCAPE '!',不能只写'%10%%' - 繁体/简体统一匹配?MySQL 推荐
utf8mb4_unicode_ci;PostgreSQL 用ILIKE配合unaccent()函数 -
LIKE不匹配NULL,要查空值得额外加OR column IS NULL
真正卡住人的从来不是语法写不对,而是把LIKE当全文检索使——它只做字符序列比对,不理解分词、同义、拼音或语义。该上MATCH AGAINST、tsvector或 Elasticsearch 的地方,硬扛只会拖垮整个库。











