假设,你现在维护一个支持邮箱登录的系统,用户表是这么定义的:
create table SUser(ID bigint unsigned primary key,
email varchar(64),
... )engine=innodb;
由于要使用邮箱登录,所以业务代码中一定会出现类似于这样的语句:
mysql> select f1, f2 from SUser where email='xxx';
可以建立两种索引
mysql> alter table SUser add index index1(email);
或
mysql> alter table SUser add index index2(email(6));
直接创建完整索引
其中 第一个句式使用的是email作为索引,第二个是使用email前6个字符作为前缀索引。
email 索引结构
前缀索引结构
前缀索引
前缀索引可能会导致额外的扫描成本(重复值)。为了解决这个问题 可以用distinct 来作区分度选择。
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;
倒序索引
倒序索引
mysql> select field_list from t where id_card = reverse('input_id_card_string');
由于身份证号的最后 6 位没有地址码这样的重复逻辑,所以最后这 6 位很可能就提供了足够的区分度。当然了,实践中你不要忘记使用 count(distinct) 方法去做个验证。
hash字段做索引
mysql> alter table t add id_card_crc int unsigned, add index(id_card_crc);
然后每次插入新记录的时候,都同时用 crc32() 这个函数得到校验码填到这个新字段。由于校验码可能存在冲突,也就是说两个不同的身份证号通过 crc32() 函数得到的结果可能是相同的,所以你的查询语句 where 部分要判断 id_card 的值是否精确相同。
网友评论