《MySQL学习》 字符串字段添加索引技巧 2
一.前缀索引
当某个字段的类型是varchar时,并且值很长时,如果建立全字段索引,将占用大量的空间。因此,可以建立前缀索引。
mysql> create table SUser( ID bigint unsigned primary key, email varchar(64), ... )engine=innodb;
前缀索引
alter table SUser add index index2(email(6));
但前缀取多长合适? 太短导致大量回表操作增加匹配行数,太长又失去了节省空间的价值,我们可以先确定一个合适的区分度,然后通过SQL去查询匹配合适的值,确定前缀索引的长度
mysql> select count(distinct left(email,4))as L4, count(distinct left(email,5))as L5, count(distinct left(email,6))as L6, count(distinct left(email,7))as L7, from SUser;
二.前缀索引对覆盖索引的影响
以上述建表语句为列
select id,email from SUser where **********';
如果使用普通索引,完全可以通过覆盖索引将数据返回给server层,而如果使用前缀索引,需要根据主键回表主键索引表去查询完整的email字段值,即使你将 前缀索引 的定义修改为 email(整个字段的长度) 的前缀索引,这时候虽然 index2 已经包含了所有的信息,但 InnoDB 还是要回到 id 索引再查一下,因为系统并不确定前缀索引的定义是否截断了完整信息。
三.其他对字符串字段建立索引的方式
除了前缀索引,其实我们还可以使用hash字段,新增一个整数字段,来保存身份证的校验码,同时在这个字段上创建索引。
mysql> alter table t add id_card_crc int unsigned, add index(id_card_crc);
然后每次插入新记录的时候,都同时用 crc32() 这个函数得到校验码填到这个新字段。由于校验码可能存在冲突,也就是说两个不同的身份证号通过 crc32() 函数得到的结果可能是相同的,所以你的查询语句 where 部分要判断 id_card 的值是否精确相同。
mysql> select field_list from t where id_card_crc=crc32('input_id_card_string') and id_card='input_id_card_string'
但使用此种方式,将不在支持范围查询,且需要额外的判断条件