✅什么是前缀索引,使用的时候要注意什么?

✅什么是前缀索引,使用的时候要注意什么?

典型回答

前缀索引是一种对字符串类型字段进行索引优化的方式。它通过只索引字符串字段的前若干字符,而不是整个字段,从而减少索引大小并提高性能。前缀索引常用于处理长文本字段或变长字符串字段,如 VARCHARTEXT

假如说我们有一个字段,内容非常的长,比如URL、邮箱地址、家庭住址等,他们就会比较长,那么如果全部都放到索引中,不仅会占用更多的空间,同时也会导致性能下降。

而前缀索引就是说我不要把整个字段都放到索引中,而是保留前N个字符来生成索引。 比如说在一个 VARCHAR(255) 字段上,索引的默认存储会包含整个字符串内容,而通过前缀索引INDEX (address(10)) ,就能为name字的前10个字符创建索引,从而减少索引存储空间。

所以他的用法就是在常见索引时指定前缀长度:

CREATE TABLE example (
    id INT NOT NULL,
    name VARCHAR(255),
    INDEX (name(10)) -- 为 `name` 字段的前 10 个字符创建索引
);

这么做的好处非常明显,就是可以减少索引占用的磁盘空间,一个索引占用的空间小了,B+树中能存放的索引的数量就更多了,那么检索起来性能也就会更好了。而且后期的维护成本也会低很多。

但是,这么做会带来一些问题的,一定要注意

  • 精确匹配能力下降:由于只索引部分字段内容,前缀索引在字段值高度相似时可能导致索引失效。比如身份证号的前几位、
  • 无法用于覆盖索引:覆盖索引要求索引中存储完整字段,而前缀索引仅存储部分内容,无法满足需求。
  • 选择性依赖于 N 的选择:如果前缀长度选得过短,可能导致索引重复率较高,降低查询性能。而太长的话有没有太大意义。

比如我之间遇到过的那个死锁的问题,就是因为前缀设置的不合理导致的。

✅数据库死锁问题排查过程

所以,这个前缀索引的前缀的长度,需要选择一个合理的值,重复度不能太高,但是又不能太长。具体的设置方式就要根据具体的字段的数据的分布情况来设定了。但是有个基本原则就是一定不能用选择性不高的前缀长度。

啥叫选择性,可以看下下面这篇文章:

✅为什么MySQL会选错索引,如何解决?

简单的选择性公式:**选择性=不重复前缀数量/总记录数,**选择性越高,说明索引效果越好

举个例子, 假设有一个包含邮箱的表

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    email VARCHAR(255)
);

邮箱的特点是,前几位通常就足以区分大多数记录。例如:

hollis@163.com
hollis@qq.com
javabagu@163.com
caixukun@gmail.com

通过计算选择性SELECTCOUNT(DISTINCTLEFT(email, N)) /COUNT(*) AS selectivity FROM users; ,结果如下:

  • 前缀长度小于等于6时:选择性为 0.5
  • 前缀长度为7时:选择性为 1.0

所以,我们就可以选择7作为我们的前缀长度。