大家好,我是 Snow Hide,作为《MySQL 实战》这个专栏的学员之一,这是我打卡的第 24 天,也是我第 83 次进行这种操作。
今天我温习了该专栏里一篇叫《怎么给字符串字段加索引?》的文章。
关键词总结:如何为邮箱字段建立合理的索引?(创建前缀索引、前缀索引可能产生的问题、建立索引时需要关注的点)、前缀索引对覆盖索引的影响(无法利用覆盖索引)、其他处理方式(倒序存储、使用 hash 字段、两种方法的区别)、字符串字段创建索引的几种方式。
所学总结:
如何为邮箱字段建立合理的索引?
创建前缀索引
- 非前缀索引:索引名(字段名),如:
index1(varchar_field)
; - 前缀索引:索引名(字段名(前缀长度)),如:
index1(varchar_field(6))
。
前缀索引可能产生的问题
可能会导致查询语句读数据的次数变多。使用前缀索引时,定义合理的前缀长度,可以做到既节省空间,又不用额外增加太多的查询成本。
建立索引时需要关注的点
分区度越高越好。因为分区度越高,意味着重复的键值越少。因此,我们可以通过统计索引上有多少个不同的值来判断要使用多长的前缀。
前缀索引对覆盖索引的影响
使用前缀索引可能会增加扫描行数,这会影响到性能。
无法利用覆盖索引
使用前缀索引就用不了覆盖索引对查询性能的优化了,这是在选择使用前缀索引时需要考虑的因素之一。
其他处理方式
索引选取的越长,占用的磁盘空间就越大,相同的数据页能放下的索引值就越少,搜索的效率也就越低。
倒序存储
将数据倒过来存储。由于身份证号的最后 6 位没有地址码这样的重复逻辑,所以最后这 6 位很可能就提供了足够的分区度。
使用 hash 字段
在表上创建一个整数字段以保存身份证的校验码,并为字段创建索引。使用 crc32()
这个函数得到校验码后插入到该字段。crc32()
函数得到的结果可能相同,所以查询时还需要连同身份证字段的值一起判断以确保精确度。
两种方法的区别
- 倒序存储方式在主键索引上,不会消耗额外的存储空间,而 hash 字段方法需要增加一个字段。但是,倒序存储使用 4 个字节的前缀长度是不够的,再长的话其消耗就和 hash 字段类似了;
- 在 CPU 消耗方面,倒序写和读的时候,都需要额外调用一次
reverse()
函数,而 hash 方式需要额外调用一次crc32()
函数。只看函数复杂度的话,reverse()
函数的 CPU 消耗会小一些; - 查询效率来看,使用 hash 方式性能会更稳定一下。因为
crc32()
所计算的值虽然有冲突,但概率非常小,可以认为每次查询的平均扫描行数接近 1.而倒序方式毕竟是用前缀索引,是会增加扫描行数的。
字符串字段创建索引的几种方式
- 完整索引:比较占空间;
- 前缀索引:节省空间,会增加查询扫描行数,且不能使用覆盖索引;
- 倒序存储:用于绕过字符串本身前缀的区分度不够的问题;
- hash 字段及其索引:查询性能稳定,有额外的存储和计算消耗,跟第三种方式一样,都不支持范围扫描。
末了
重新总结了一下文中提到的内容:如何为邮箱字段建立合理的索引?、前缀索引对覆盖索引的影响、其他处理方式、字符串字段创建索引的几种方式。