前缀索引

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”, 而学号的规则是:十五位的数字,其中前三位是所在城市编号、第四到第六位是学校编号、第七位到第十位是入学年份、最后五位是顺序编号。

系统登录的时候都需要学生输入登录名和密码,验证正确后才能继续使用系统。就只考虑登录验证这个行为的话,你会怎么设计这个登录名的索引呢?

参考回复:

  1. 从业务量预估优化和收益。一个学校每年预估 2 万新生,50 年才 100 万记录,能节省多少空间,直接全字段索引。省去了开发转换及局限性风险,碰到超大量迫不得已再用后两种办法。
  2. 可以把学号使用 bigint 存储,占 8 个字节,比前缀索引空间占用要小。跟 hash 索引比,也有区间查询的优势。