目 录CONTENT

文章目录

MySQL LIKE 索引字段你以为的失效可能不是失效

MWSFOT
2022-09-30 / 0 评论 / 0 点赞 / 116 阅读 / 718 字

前提

  1. 需要明确什么是索引
  2. MySQL索引使用规则
    这两点基本上八股文都会背,就不赘叙了.

问题

为什么这么说呢,相信都有看到,如果在使用LIKE 查询的时候 将 % 放在前面那么%filed filed字段索引将会失效,违背了索引有序排列的规则,就会造成索引失效,从而进行全表扫描
这时候的设计方式就是将%放在右侧,即filed %格式,此时索引就能正常使用

那会不会有一种情况,即使使用了filed %格式,mysql 也没有使用索引去进行查询 ?

看一种情况:
这是一个学员离职入职历史记录表 company_staff_history , 注释都有标明
学员表
其中, up_org_codes是根据各级行政区划编码当前公司的自定义编码以逗号隔开的字符串
也是本次测试使用的字段,看一下格式:
image-1664526936829
再确认下记录总数:
image-1664526998788
总共 93253 条数据
再确认下分布规律:
image-1664527114807
最多的为0000000000,6100000000,6101000000,6101920000,6101920019 占4889条

想要的一个结果,我们通过up_org_codes字段 查询 0000000000,6100000000,6101000000下的数据
**语句: **

select * from company_staff_history c where c.up_org_codes like "0000000000,6100000000,6101000000%"

按照之前我们学到的结论,这个字段是会走索引的,没问题吧,看一下结果:
image-1664527537913
它竟然没有走索引,或者说mysql没有使用索引去查询结果,结果一共 91875 条. 啧,跟我们想象的不一样

再试下 查询 0000000000,6100000000,6101000000,6101130000 下的学员信息

image-1664527735396
此时竟然又能使用索引,或者说mysql选择去使用索引了, 结果一共2053条, 这可有点不得所以然了

恩,别急且听我慢慢道来, 不知道细心的同学有没有注意到,我在测试中十分注意数字,注意此处mysql执行计划rows只能起到参考意义,来列一下:

  1. company_staff_history 总条数 93253
  2. 0000000000,6100000000,6101000000右模糊查询 总条数 91875
  3. 0000000000,6100000000,6101000000,6101130000右模糊查询 总条数 2053

第二次匹配mysql 给出的计划总条数就差了不到1300条左右,而第三次匹配差了9w之多,而在这个测试表中全都是以
0000000000开头,而6100000000,占了大多数有63564条,这给了mysql一种错觉,以0000000000,6100000000,6101000000,6101130000开头的,则
image-1664528308747
实际上只占了28020
看下查询效率对比:

未使用索引: 0.443s
image-1664528550482
使用索引 0.358s
image-1664528669373

再往前进一步
查询0000000000,6100000000匹配结果
未使用索引: 0.746s左右
image-1664528766515
使用索引: 0.733s
image-1664528642670

越往前推演,就越接近全表扫描了,直至开头
使用索引:
image-1664528944652
image-1664529006619
当然这里涉及到其他mysql内部的逻辑,后续再研究
所以…

0

评论区