《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'

但使用此种方式,将不在支持范围查询,且需要额外的判断条件

全部评论

相关推荐

头像
不愿透露姓名的神秘牛友
04-29 12:10
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务