前缀索引,是指对于varchar/text/blob类型的字段建立索引时一般都会选择前N个字符作为索引。
因为索引很长的字符列,会让索引变得大且慢。索引开始的部分字符,这样可以大大节约索引空间,从而提高索引效率,但这样也会降低索引的选择性

索引的选择性是指不重复的索引值(也称为基数,cardinality)和数据表的记录总数的比值。

计算公式:

1
select count(distinct(字段名))/count(*) from 表名;

比值约接近于1,说明选择性越好,说明不重复的值的行数约接近总数。

那怎么选择一个varchar/text/blob的字段应该选择前N个字符呢?如何确定N的大小呢?有没有科学衡量的方法?
答案是有的。

计算方法如下:

例如表名为text_blob, 字段名为a

1
2
3
4
5
6
7
8
9
10
mysql> select count(distinct(a))/count(*) e,
-> count(distinct(left(a,1)))/count(*) e1,count(distinct(left(a,2)))/count(*) e2,count(distinct(left(a,3)))/count(*) e3,
-> count(distinct(left(a,4)))/count(*) e4,count(distinct(left(a,5)))/count(*) e5,count(distinct(left(a,6)))/count(*) e6,
-> count(distinct(left(a,7)))/count(*) e7,count(distinct(left(a,8)))/count(*) e8 from text_blob;
+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| e | e1 | e2 | e3 | e4 | e5 | e6 | e7 | e8 |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| 1.0000 | 0.0225 | 0.4663 | 0.8618 | 0.9734 | 0.9958 | 0.9992 | 0.9992 | 1.0000 |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+
1 row in set (0.02 sec)

left函数按照不同的长度计算比值,找到一个和完整列比例接近的值,比如上面e5前5个长度比例达到0.9958,已经很接近1了,综合考虑比较合适。
最后,开开心心把索引建上:)

1
alter table text_blob add key (a(5));