ZBLOG

为什么mysql模糊查询`谢%`的时候会走索引,但是`%谢`的时候就不会走索引

MySQL的模糊查询是否使用索引取决于查询模式的具体形式,这与B+树索引的结构和存储方式密切相关。以下是详细解释:


1. 索引结构原理

  • MySQL的InnoDB默认使用B+树索引,这种索引按照字段值的前缀顺序存储(例如字符串按字符逐位排序)。
  • 索引的检索过程是从左到右匹配键值。例如,字段 name 的索引会先比较第一个字符,然后第二个字符,依此类推。

2. 谢% 为什么走索引?

  • 模式匹配逻辑
    查询条件 WHERE name LIKE '谢%' 意味着:
       - 第一个字符必须是“谢”(固定前缀)。
       - 后续字符可以是任意值(通过索引范围扫描即可覆盖)。
    
  • 索引适用性
    由于B+树索引按字典序排列,所有以“谢”开头的字符串在索引中是连续存储的。因此,MySQL可以通过索引范围扫描(Range Scan) 快速定位到第一个以“谢”开头的记录,然后顺序遍历直到不满足条件的记录为止。
  • 执行计划示例
    若使用 EXPLAIN 分析查询,会显示 type: rangekey: [index_name],表明使用了索引。

3. %谢 为什么不走索引?

  • 模式匹配逻辑
    查询条件 WHERE name LIKE '%谢' 意味着:
       - 最后一个字符必须是“谢”,但前面的字符任意。
    
  • 索引不适用原因
    • B+树索引是从左到右排序的,而通配符 % 在开头表示前缀不确定,无法利用索引的顺序性。
    • MySQL无法快速定位满足条件的记录,必须扫描所有条目(逐行检查末尾是否为“谢”),相当于全表扫描。
  • 执行计划示例
    EXPLAIN 会显示 type: ALL(全表扫描),且 key: NULL(未使用索引)。

4. 特殊情况与优化建议

  • 反转字符串(Reverse Index)优化
    如果业务中频繁需要后缀查询(如 %谢),可额外创建一个反向字段(例如 name_reverse = reverse(name)),并为其建立索引。查询时改为:

    ```sql
    WHERE name_reverse LIKE reverse('%谢') -- 即 '谢%'
    ```
    

    这样可利用反向字段的索引加速查询。

  • 全文索引(FULLTEXT)适用场景
    如果需求是模糊匹配文本内容(而非严格后缀),可考虑使用MySQL的全文索引(FULLTEXT),但需注意其适用于词条匹配而非任意位置通配。

  • 覆盖索引的局限性
    即使某些情况下数据库可能选择扫描整个索引(而非全表)来避免回表(Covering Index),但对于 %谢 这类条件,仍然需要遍历所有索引条目,效率提升有限。


5. 总结

查询模式 是否走索引 原因
谢% ✅是 B+树索引支持前缀匹配,可进行范围扫描。
%谢 ❌否 无法利用索引的顺序性,必须逐行判断后缀。
%谢% ❌否 前后均不确定,除非使用全文索引或其他优化手段。

如果需要高效处理后缀或中间模糊查询,建议结合业务需求选择更合适的方案(如反向字段、全文检索或外部搜索引擎如Elasticsearch)。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=24164

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?