MySQL -- 索引 二 字符串普通索引

全字段索引

就是给整个字段加索引,索引存储整个字段的值。
数据量较小时,查询成本高,准确度高;
数据量较大时,比较耗费空间;
如对 summery (varchar(64)) 字段,添加全字段索引

1
mysql> ALTER TABLE tb1 ADD INDEX summery_idx(summery);

前缀索引

MySQL支持定义字符串的前面的一部分字节作为索引。
查询成本低,比较节省空间;
使用前缀索引查询时,每次遇到符号查询条件的记录都要回表判断一次,增加查询语句读数据的次数,也就是增加扫描行数;
使用前缀索引时无法使用覆盖索引对查询的性能优化;

1
mysql> ALTER TABLE tb1 ADD INDEX summery_idx(summery(10));

对于 TEXT 类型字段,如使用普通字符串索引,只能使用前缀索引。

查询隐式转换

1、 当操作符左右两边的数据类型不一致时,会发生隐式转换。
2、 当where查询操作符左边为数值类型时发生了隐式转换,那么对效率影响不大,但还是不推荐这么做。
3、 当where查询操作符左边为字符类型时发生了隐式转换,那么会导致索引失效,造成全表扫描效率极低。
4、 字符串转换为数值类型时,非数字开头的字符串会转化为0,以数字开头的字符串会截取从第一个字符到第一个非数字内容为止的值为转化结果。

如:

1
2
3
4
5
// 得到正确结果,使用索引,查询效率高
mysql> SELECT summery FROM tb1 WHERE summery = '123';

// 得到正确结果,但不使用索引,查询效率低
mysql> SELECT summery FROM tb1 WHERE summery = 123;

所以,在写SQL时要养成良好的习惯,查询的字段是什么类型,等号右边的条件就写成对应的类型。特别当查询的字段是字符串时,等号右边的条件一定要用引号引起来标明这是一个字符串,否则会造成索引失效触发全表扫描。

常见问题

1、 如存储学号时,比如201306070110。前四个字节表示入学年份,区分度较低,此时可以采用倒序存储, 也就是 字段值存储 011070603102,然后再使用前缀索引的方式提高查询效率,查询的时候也要用学号倒序来查询;

2、存储邮箱时,比如 streamXXX@email.com,此时正序和倒序的区分度都比较低,这时就可以考虑添加一个字段存储hash后的值,再对这个hash字段建立索引,查询的时候也要使用hash后的值进行查询。