主题
面试速答(先看这里)
**一句话结论:**前缀索引是一种对字符串类型字段进行索引优化的方式 。
60秒标准回答:
前缀索引是一种对字符串类型字段进行索引优化的方式 。它通过只索引字符串字段的前若干字符,而不是整个字段,从而减少索引大小并提高性能。前缀索引常用于处理长文本字段或变长字符串字段,如 VARCHAR 和 TEXT
假如说我们有一个字段,内容非常的长,比如URL、邮箱地址、家庭住址等,他们就会比较长,那么如果全部都放到索引中,不仅会占用更多的空间,同时也会导致性能下降
而前缀索引就是说我不要把整个字段都放到索引中,而是保留前N个字符来生成索引。 比如说在一个 VARCHAR(255) 字段上,索引的默认存储会包含整个字符串内容,而通过前缀索引 INDEX (address(10)) ,就能为name字的前10个字符创建索引,从而减少索引存储空间
**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点
回答主线:
- **要点1:**假如说我们有一个字段,内容非常的长,比如URL、邮箱地址、家庭住址等,他们就会比较长,那么如果全部都放到索引中,不仅会占用更多的空间,同时也会导致性能下降。
- **要点2:**而前缀索引就是说我不要把整个字段都放到索引中,而是保留前N个字符来生成索引。
- **要点3:**所以他的 用法 就是在常见索引时指定前缀长度:
- **要点4:**这么做的 好处 非常明显,就是可以减少索引占用的磁盘空间,一个索引占用的空间小了,B+树中能存放的索引的数量就更多了,那么检索起来性能也就会更好了。
- **要点5:**但是,这么做会带来一些问题的, 一定要注意 :
**记忆锚点:**前缀索引 → 无法用于覆盖索引 → VARCHAR → 从而减少索引 → 而前缀索引 → DISTINCTLEFT
关键取舍:
- 它通过只索引字符串字段的前若干字符,而不是整个字段,从而减少索引大小并提高性能。
- 假如说我们有一个字段,内容非常的长,比如URL、邮箱地址、家庭住址等,他们就会比较长,那么如果全部都放到索引中,不仅会占用更多的空间,同时也会导致性能下降。
- 所以他的 用法 就是在常见索引时指定前缀长度: 这么做的 好处 非常明显,就是可以减少索引占用的磁盘空间,一个索引占用的空间小了,B+树中能存放的索引的数量就更多了,那么检索起来性能也就会更好了。
易错提醒:
- 而前缀索引就是说我不要把整个字段都放到索引中,而是保留前N个字符来生成索引。
- 但是,这么做会带来一些问题的, 一定要注意 : 精确匹配能力下降 :由于只索引部分字段内容,前缀索引在字段值高度相似时可能导致索引失效。
加分表达:
- 前缀索引是一种对字符串类型字段进行索引优化的方式 。
- 选择性依赖于 N 的选择 :如果前缀长度选得过短,可能导致索引重复率较高,降低查询性能。
追问准备:
- 围绕「前缀索引」:底层原理是什么?使用时有哪些边界和常见坑?
- 围绕「无法用于覆盖索引」:底层原理是什么?使用时有哪些边界和常见坑?
- 围绕「VARCHAR」:底层原理是什么?使用时有哪些边界和常见坑?
- 如果线上出现异常,你会如何定位、验证并规避?
典型回答
前缀索引是一种对字符串类型字段进行索引优化的方式。它通过只索引字符串字段的前若干字符,而不是整个字段,从而减少索引大小并提高性能。前缀索引常用于处理长文本字段或变长字符串字段,如 VARCHAR 和 TEXT。
假如说我们有一个字段,内容非常的长,比如URL、邮箱地址、家庭住址等,他们就会比较长,那么如果全部都放到索引中,不仅会占用更多的空间,同时也会导致性能下降。
而前缀索引就是说我不要把整个字段都放到索引中,而是保留前N个字符来生成索引。 比如说在一个 VARCHAR(255) 字段上,索引的默认存储会包含整个字符串内容,而通过前缀索引 INDEX (address(10)) ,就能为name字的前10个字符创建索引,从而减少索引存储空间。
所以他的用法就是在常见索引时指定前缀长度:
plain
CREATE TABLE example (
id INT NOT NULL,
name VARCHAR(255),
INDEX (name(10)) -- 为 `name` 字段的前 10 个字符创建索引
);这么做的好处非常明显,就是可以减少索引占用的磁盘空间,一个索引占用的空间小了,B+树中能存放的索引的数量就更多了,那么检索起来性能也就会更好了。而且后期的维护成本也会低很多。
但是,这么做会带来一些问题的,一定要注意:
- 精确匹配能力下降:由于只索引部分字段内容,前缀索引在字段值高度相似时可能导致索引失效。比如身份证号的前几位、
- 无法用于覆盖索引:覆盖索引要求索引中存储完整字段,而前缀索引仅存储部分内容,无法满足需求。
- 选择性依赖于 N 的选择:如果前缀长度选得过短,可能导致索引重复率较高,降低查询性能。而太长的话有没有太大意义。
比如我之间遇到过的那个死锁的问题,就是因为前缀设置的不合理导致的。
所以,这个前缀索引的前缀的长度,需要选择一个合理的值,重复度不能太高,但是又不能太长。具体的设置方式就要根据具体的字段的数据的分布情况来设定了。但是有个基本原则就是一定不能用选择性不高的前缀长度。
啥叫选择性,可以看下下面这篇文章:
简单的选择性公式:**选择性=不重复前缀数量/总记录数,**选择性越高,说明索引效果越好
举个例子, 假设有一个包含邮箱的表
plain
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255)
);邮箱的特点是,前几位通常就足以区分大多数记录。例如:
plain
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作为我们的前缀长度。