栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

rows超过总行数30%索引失效

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

rows超过总行数30%索引失效

虽然说现在的搜索范围是using where 是一个满足目前开发的一个效率,但我认为还是有可以优化的空间的。
目前是这样,有一个单列索引a,还有一个联合索引a_b_c
我们的查询条件是这样
select * from table where a = xx and b = xx and c = xx and d= xx and f = xx
有的查询还用到了like 不过那个字段也是索引的,还有用到了in的,也是上了索引的,这里就简化不说了。
目前用到的索引是 a。我就很纳闷,有单列索引a和联合索引a_b_c为啥不用联合索引?

联合索引怎么也比单列索引精度高啊!
或许我们不应该过于信任mysql的优化器。
这次比较单列索引a 和联合索引 a_b_c要看两个东西。
一个是rows 一个是filtered:符合某条件的记录数百分比。
目前索引是单列索引a,explain发现定位到的行数是:
rows:210
fitered:10

通过use index(a_b_c)强制使用联合索引,发现mysql需要对比
rows需要对比的行数:1035
fitered:3.13
type:all
key:null
好家伙 联合索引失效

这个联合索引为什么失效呢?顺便一说我为了实验的变量可控性
我使用的where里面的过滤字段只有a,b,c由于mysql版本,也没用‘>'来设置条件/
查了一下,有一种情况下索引会失效,mysql会认为走了全表

单次查询如果查出表的大部分数据,这会导致编译器认为全表扫描性能比走索引更好,从而导致索引失效。一般单次查询数量大概占大表的30%以上索引会失效。

比如上面行数1035 但是一共表里数据就1100多条。
这种情况来看 即使a字段筛选度高也不该选用。

当然这也和我where 里面选择的值有关系,我设置的是 where a < max
这可不就走了全表。
换了个稍微小一点的值,rows没超过全部的百分之30,单列索引a又正常工作了。
但为什么没走联合索引?强制它走联合索引。
发现行数相同,命中率单列是7,联合是3.

总结:虽然说我们设置联合索引的时候,要选择区分度最高的,就像很多人很多博客都说过的那样,城市和性别一起做联合索引要把城市放前面。
事实上,当数据过于分散的情况下,拿城市做打头的也不太合适。

但是这不代表区分度越高越好,比如说时间戳非常不合适。
当你的时间戳字段排序好,当你要找的部分命中行数正好是前百分之30时这是可以正常工作的。但是查询时传值是由用户输入来决定的,并不知道用户会输入哪一段时间。
而且时间戳 bigint类型,还存在作为索引时,‘>'会失效的情况。很奇怪,虽然网上有人说这是由于mysql版本是5.7的原因,但是int类型索引,用‘>'并不会失效?

下一步就准备研究下这个问题,要是有大佬清楚为什么也麻烦告知。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/284091.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号