前缀索引
MySQL 是支持前缀索引的。默认地,如果你创建索引的语句不指定前缀长度,那么索引就会包含整个字符串。
mysql> alter table teacher add index index1(email);
mysql> alter table teacher add index index2(email(6));
前缀索引与覆盖索引
如果使用前缀索引,那么就无法使用覆盖索引。
select id, email from teacher where email = '12345678@qq.com';
例如上面的查询语句,如果建立一个 email(6) 的索引,那么还需要回表查询;如果建立一个 email(15) 的索引,虽然包含了全部的信息,但是还是需要回表查一下,因为系统不清楚前缀索引中是否包含了全部的信息。
基于身份证建立索引
地方公安局存储身份证信息。由于身份证前面的数据为地址信息,因此前缀索引会出现较短-区分度小,较长-内存大。
- 倒序存储 + 前缀索引。
where id_card = reverse('code_string') - hash 字段。
where id_card_crc = crc32('code_string') and id_card = 'code_string';
前者好处在于,倒序的计算速度比 crc32 计算更快,但后者不用进行字符串比较。
根据数据规模来确定是否使用前缀索引
如果你在维护一个学校的学生信息数据库,学生登录名的统一格式是 “学号@gmail.com”, 而学号的规则是:十五位的数字,其中前三位是所在城市编号、第四到第六位是学校编号、第七位到第十位是入学年份、最后五位是顺序编号。
系统登录的时候都需要学生输入登录名和密码,验证正确后才能继续使用系统。就只考虑登录验证这个行为的话,你会怎么设计这个登录名的索引呢?
参考回复:
- 从业务量预估优化和收益。一个学校每年预估 2 万新生,50 年才 100 万记录,能节省多少空间,直接全字段索引。省去了开发转换及局限性风险,碰到超大量迫不得已再用后两种办法。
- 可以把学号使用 bigint 存储,占 8 个字节,比前缀索引空间占用要小。跟 hash 索引比,也有区间查询的优势。