LIKE '%关键词%' 一定慢是因为B+树索引仅支持最左前缀匹配,无确定前缀起点,优化器被迫全表扫描,EXPLAIN显示type: ALL、key: NULL、rows≈总行数。
后缀匹配()能走索引,全文索引适合任意位置匹配——但两者适用场景完全不同,不能混用。
为什么
一定慢?
数据库的 B+ 树索引是按值从左到右排序存储的,
没有确定的前缀起点,优化器无法跳转到索引某一段,只能全扫描。哪怕字段有索引,
的
字段也会显示
或
,
值接近总行数。
常见错误现象:
百万级表查一个
耗时 3~8 秒,而同样数据量的
只要 20ms
加了索引却没生效,
列在
中仍为
查询只返回几条结果,但
显示扫描了上百万行
改用
的实操要点
这是最轻量、兼容性最好的优化方式,但要求业务能接受“仅匹配开头”的限制。
前端输入框需配合提示:例如用户输“张”,自动补全建议“张三”“张伟”,避免让用户手动加
后端 SQL 必须写成
,而不是拼接
如果字段允许为空,
条件不能和
写在同一层
中,否则可能让索引失效
索引列顺序很重要:若查询条件还有
,建议建联合索引
,而非单列
什么时候必须上全文索引?
当业务明确需要“包含关键词”“前后都模糊”“支持同义词或拼音”时,
已无解,必须换引擎。
SQL Server 用
,查询改用
或
,不是
MySQL 5.6+ 的
对中文分词支持弱,生产环境慎用;更推荐 Elasticsearch,尤其已有日志/搜索基建的项目
注意数据同步延迟:全文索引不是实时的,Elasticsearch 默认 1 秒刷新,SQL Server 全文索引也有爬网间隔
不要在小表(
容易被忽略的细节
很多人试过
还是慢,或者全文索引查不到数据,问题往往不在方案本身:
不匹配会导致索引失效,比如字段是
,而连接字符集是
MySQL 中
和
函数即使字段有索引,也无法利用索引加速,它们仍是全表扫描
SQL Server 的全文索引默认不索引停用词(如“的”“了”),搜这些词会直接返回空,且不会报错
MyBatis 的
标签拼接
时,如果参数为空,可能生成
,等于强制全表扫
LIKE '关键词%'LIKE '%关键词%'LIKE '%关键词%'EXPLAINtypeALLindexrowsLIKE '%张%'LIKE '张%'keyEXPLAINNULLrowsLIKE '关键词%'%WHERE name LIKE CONCAT(?, '%')'%' + ? + '%'IS NULLLIKEORstatus = 1(status, name)nameLIKECREATE FULLTEXT INDEXCONTAINS()FREETEXT()LIKEMATCH ... AGAINSTLIKE '关键词%'COLLATIONutf8mb4_0900_as_csutf8mb4_general_ciINSTR()LOCATE()LIKELIKE '%%'