like '%keyword' 一定走全表扫描,因b+tree索引仅支持前缀匹配,无法定位关键字在字符串中的任意位置;reverse()+函数索引可优化右模糊查询,但需预先建索引且模式需调整为'rekwod%'。

LIKE '%keyword' 为什么一定走全表扫描
B+Tree 索引的物理结构决定了它只能高效支持「前缀匹配」。索引页内数据按字段值字典序排列,查找时从根节点逐层定位到叶子节点。当查询条件是 LIKE '%keyword',数据库无法预知 keyword 出现在字符串哪个位置——开头?中间?结尾?这破坏了有序性的利用前提,优化器只能放弃索引,退化为逐行扫描。
reverse() + LIKE 能绕过这个限制吗
能,但有严格前提:必须配合函数索引(MySQL 8.0+)或生成列索引(5.7+)。单纯写 WHERE REVERSE(column) LIKE REVERSE('%keyword') 不会自动走索引;你得先建索引:
ALTER TABLE t ADD COLUMN reversed_name VARCHAR(100) AS (REVERSE(name)) STORED;CREATE INDEX idx_reversed_name ON t(reversed_name);- 再查
WHERE reversed_name LIKE 'rekwod%'(注意:reverse 后的模式要变成右模糊)
没建这个索引,REVERSE() 就只是个计算函数,照样触发索引失效。
LOCATE() / INSTR() 查询真的比 LIKE 快吗
在无索引场景下,LOCATE('keyword', column) > 0 和 column LIKE '%keyword%' 都是全表扫描,性能差异微乎其微。它的“快”是假象——因为执行计划里都显示 type: ALL,IO 和 CPU 消耗本质一致。真正提速的前提是:字段本身有索引且你用的是右模糊(keyword%),此时 LIKE 可走索引,而 LOCATE() 因含函数调用反而无法使用索引。
全文索引是唯一靠谱的替代方案吗
对中文或混合语言场景,FULLTEXT 索引不是“替代”,而是“正解”。MATCH(column) AGAINST('keyword' IN NATURAL LANGUAGE MODE) 会走倒排索引,支持分词、权重、相关性排序。但它不支持通配符前缀,也不能代替精确匹配。如果你的业务既要模糊又要高并发响应,别硬拼 LIKE,尽早切到 FULLTEXT 或外部搜索引擎(如 Elasticsearch)。函数索引和 reverse 技巧只适合极少数固定后缀场景(比如查所有以 .pdf 结尾的文件名),别当成通用解法。











