为什么重复值高的列(比如性别)不能作为索引?

这是一道面试题,我先讲一下我的思路,如果有错误请各位指点
当我们以某一列sex作为二级索引时,在B+树中:

  • 每一个叶子节点存储了多条页,这些页存储了主键值和索引列sex数据,并且这些数据根据sex来排列。
  • 每一个非叶子节点里则同样存储了多条页,每条页中存储了到达下一层节点中的页号,主键值和sex列数据。这些数据同样按照sex值排序。

这里我用<<MySQL是怎样运行的:从根儿上理解MySQL>>书里的图来大致描述这个结构:
img

当我们查询条件的是索引列sex时,遍历这颗b+树,拿条件中的sex值和非叶子节点中的每个页里的sex值进行比较,从而确定到达下一层节点的某个页,进而最终到达某个叶子节点中的某条页。
如果索引列sex的值是重复的,那么在非叶子节点中的比较过程中,如果该节点中的每条页的sex值和查询条件的sex值都相同,就无法确定应该到达下一层的哪一个页中。
我看书上说在非叶子节点的比较过程中,如果索引列都相同的情况下,就比较主键值。那么如果查询条件里没有主键值,那么应该怎么查找?全表查找吗?

全部评论
innodb中的表是不会没有主键的。如果你创建表没有显示指定主键,那么innodb会选择第一个非空唯一的列作为主键,如果没有非空唯一的列,那么innodb会创建一个6字节的隐藏字段作为主键。innodb里面表的组织形式是索引组织表,存储形式是b+树,一定要有某个列作为排序的依据的,就是主键列
点赞 回复 分享
发布于 2020-08-28 14:40
我觉得查找过程是这样的,找到第一个sex满足条件的行所在的叶子结点,然后顺序遍历直到第一个不满足条件的列。至于为什么性别这种做索引不合适?这是因为优化器是基于查询代价的优化方法,如果索引选择性太低,那在非主键索引树上扫描的行数就会很多,再加上二次回表会导致查询代价过大,不如直接扫全表,一般优化器估计扫描行数达到总行数的三分之一以上,就放弃走索引了,索引会失效。
点赞 回复 分享
发布于 2020-08-28 14:31

相关推荐

03-29 12:10
门头沟学院 C++
挣K存W养DOG:散漫消极者淘汰,一眼坑爹。实习几个月转正的时候说你加班太少,能力还行态度不够积极裁了,马上老实。
点赞 评论 收藏
分享
牛客10001:问就是六个月,全国可飞,给钱就干
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客企业服务