(1)字段基数问题:
举例:有一个字段一共10万行数据里有10万个值,结果这10万个值,要不然是0,要不然是1,那么他的基数就是2,为什么?因为这个字段的值就两个选择 0和1,假设要针对这种字段建立索引,那还不如全表扫描,因为索引树仅包含0和1两种值,根本没法进行快速的二分查找,也根本没太大的意义,所以这种时候选用基数很低的字段放索引里意义不大。
一般建立索引,尽量使用基数比较大的字段,就是值比较多的字段,才能发挥B+树快速二分查找的优势,其次尽量对那些字段的类型比较小的列来设计索引,比如tinyint之类的,因为字段类型比较小,说明这个字段本身的值占用的磁盘空间小,此时搜索的时候性能会好一点。
不过当然字段类型小一点的列,也不是绝对的,很多时候要针对VARCHAR(255)这种字段建立索引,哪怕多占一些磁盘空间,也得去设计这样的索引,比较关键的其实还是尽量别把基数太低的字段包含在索引里,因为意义不大。
万一真有varchar(255)的字段,里面的值太大,放索引树里太占磁盘空间,此时可以换一种策略,也就是仅针对varchar(255)字段的前20个字符建立索引,对这个字段的每个值的前20个字符放在索引树里,建立出的索引类似 KEY my_index(name(20),age,cousrse),就这样一个形式,假设name是varchar(255)类型的,在索引树里对name的值仅仅提前20个字符而已。
此时在where条件里搜索的时候,根据name字段来搜索,此时就会先到索引树里根据name字段的前20个字符去搜索,定位到之后前20个字符的前缀匹配的部分数据之后,再回到聚簇索引提取出完整的name值进行比对就可以了。
但是假设是 order by name,此时name因为在索引树里仅仅包含前20个字符,所以这个排序是没法用上索引,group by同理。
(2)总结:
重点说了索引字段的基数和前缀索引,记住两点,字段基数很低的列尽量别包含到索引里去,还有对那种比较长的字符串类型的列,可以设计前缀索引,仅仅包含部分字符到索引树里去,where 查询还是可以用的,但是order by 和 group by 就用不上了。