当前位置:网站首页>MySQL 45 讲 | 11 怎么给字符串字段加索引?
MySQL 45 讲 | 11 怎么给字符串字段加索引?
2022-08-04 10:48:00 【蓝布棉】
11 | 怎么给字符串字段加索引?
如何在邮箱这样的字段上建立合理的索引 ?
第一个语句创建的index1索引里面,包含了每个记录的整个字符串;
第二个语句创建的index2 索引里面,对于每个记录都是只取前6个字节
mysql> alter table SUser add index index1(email); mysql> alter table SUser add index index2(email(6));- index 1 使用email全部字段创建索引,查找时回全表扫描。
- index 2 使用email的前6个字段创建前缀索引, 占用的空间更小,但会增加额外的记录扫描次数 。
这两个索引定义下分别执行下面查询语句:
select id,name,email from SUser where email='[email protected]';- 使用的是index1(即email整个字符串的索引结构),执行顺序是这样的:
- 从index1索引树找到满足索引值是’[email protected]’的这条记录,取得ID2的值;
- 到主键上查到主键值是ID2的行,判断email的值是正确的,将这行记录加入结果集;
- 取index1索引树上刚刚查到的位置的下一条记录,发现已经不满足 email='[email protected]’的条件了,循环结束。
- 如果使用的是index2(即email(6)索引结构),执行顺序是这样的:
- 从index2索引树找到满足索引值是’zhangs’的记录,找到的第一个是ID1;
- 到主键上查到主键值是ID1的行,判断出email的值不是’[email protected]’,这行记录丢弃;
- 取index2上刚刚查到的位置的下一条记录,发现仍然是’zhangs’,取出ID2,再到ID索引上取整行然后判断,这次值对了,将这行记录加入结果集;
- 重复上一步,直到在idxe2上取到的值不是’zhangs’时,循环结束。
使用前缀索引,定义好长度,就可以既节省空间,又不用额外增加太多的查询成本。
怎样确定应该使用多长的前缀呢?
区分度,区分度越高越好
- 可以使用下面这个语句,算出这个列上有多少个不同的值
mysql> select
count(distinct left(email,4))as L4,
count(distinct left(email,5))as L5,
count(distinct left(email,6))as L6,
count(distinct left(email,7))as L7,
from SUser;
依次选取不同长度的前缀,使用前缀索引很可能会损失区分度,所以需要预先设定一个可以接受的损失比例,比如 5%。然后,在返回的L4~L7中,找出不小于 L * 95%的值,假设这里L6、L7都满足,你就可以选择前缀长度为6。
前缀索引对覆盖索引的影响
下面两个SQL语句:
select id,email from SUser where email='[email protected]';
select id,name,email from SUser where email='[email protected]';
- 第一个语句只要求返回id和email字段。
- 如果使用index1(即email整个字符串的索引结构)的话,可以利用覆盖索引,从index1查 到结果后直接就返回了,不需要回到ID索引再去查一次。
- 如果使用index2(即email(6)索引结构)的话,不得不回到ID索引再去判断email字段的值 。
使用前缀索引就用不上覆盖索引对查询性能的优化了。
前缀的区分度不够好的情况时,怎么办呢?
比如,我们国家的身份证号,一共18位,其中前6位是地址码,所以同一个县的人的身份证号前 6位一般会是相同的。还有没有别的处理 方法呢?这种方法,既可以占用更小的空间,也能达到相同的查询效率。
- 倒序存储 : 存储身份证号候把它倒过来存,每次查询的时候,可以这么写:
select field_list from t where id_card = reverse('input_id_card_string');
使用 reverse() 函数把数字倒过来,可以用最后6位的区分度创建前缀索引,使用count(distinct)方法去做个验证 。
- hash字段:在表上再创建一个整数字段,来保存身份证的校验码, 同时在这个字段上创建索引。
alter table t add id_card_crc int unsigned, add index(id_card_crc);
select field_list from t where id_card_crc=crc32('input_id_card_string') and id_card='input_id_card_string'
用crc32()这个函数得到校验码填到这个新字段。
倒序存储和使用hash字段的异同点 :
相同点: 都不支持范围查询。 倒序存储不支持范围查询;hash字段也只能支持等值查询。
不同点:
- 额外空间: 倒序存储方式在主键索引上,不会消耗额外的存储空间;而hash字段方法需要增加一个字段。
- CPU消耗: 倒序方式每次写和读时,都需要额外调用一次reverse函数;而hash 字段的方式需要额外调用一次crc32()函数。reverse函数额外消耗的CPU资源会更小些 。
- 查询效率 : hash字段方式的查询性能相对更稳定一些,可以认为每次查询的平均扫描行数接近1 ;倒序存储 方式毕竟还是用的前缀索引的方式,也就是说还是会增加扫描行数。
小结
字符串字段创建索引的场景
- 创建完整索引,比较占用空间
- 创建前缀索引,节省空间,但会增加查询扫描次数,并且不能使用覆盖索引
- 倒序存储,再创建前缀索引,用于绕过字符串本身前缀的区分度不够的问题,不支持范围扫描
- hash字段索引,查询性能稳定,有额外的存储和计算消耗,不支持范围扫描
边栏推荐
- Digital management insight into retail and e-commerce operations - retail password
- 江西发布紧急通知:全面开展涉校涉生安全隐患大排查
- Camunda整体架构和相关概念
- 学会使用set和map的基本接口
- 图文手把手教程--ESP32 MQTT对接EMQX本地服务器(VSCODE+ESP-IDF)
- C language * Xiaobai's adventure
- 图文手把手教程--ESP32 OTA空中升级(VSCODE+IDF)
- Camunda整体架构和相关概念
- MATLAB程序设计与应用 3.2 矩阵变换
- mysql进阶(二十六)MySQL 索引类型
猜你喜欢

物体颜色的来源

Jina 实例秀|七夕神器!比你更懂你女友的AI口红推荐

vscode插件设置——Golang开发环境配置

ECCV 2022 | 清华&腾讯AI Lab提出REALY: 重新思考3D人脸重建的评估方法

解析treeSet集合进行自定义类的排序

AWS Lambda related concepts and implementation approach

【机器学习】:如何对你的数据进行分类?
![[论文阅读] Unpaired Image-to-Image Translation Using Adversarial Consistency Loss](/img/4d/9c2f94f475834771f6ad6ffe8f8b35.png)
[论文阅读] Unpaired Image-to-Image Translation Using Adversarial Consistency Loss

华为开源:聚焦开源基础软件,共建健康繁荣生态

iMeta | German National Cancer Center Gu Zuguang published a complex heatmap visualization method
随机推荐
[论文阅读] Unpaired Image-to-Image Translation Using Adversarial Consistency Loss
Servlet基础详细版
Multimedia and Internet of Things technology make the version "live" 129 vinyl records "Centennial Voice"
Super Learning Method
vscode插件设置——Golang开发环境配置
Introduction to the core methods of the CompletableFuture interface
数据化管理洞悉零售及电子商务运营——零售密码
[论文翻译] Unpaired Image-to-Image Translation using Adversarial Consistency Loss
MySQL: Integrity Constraints and Table Design Principles
RL78 development environment
BOSS 直聘回应女大学生连遭两次性骚扰:高度重视求职者安全,可通过 App 等举报
华为云安全云脑,让企业云化运营更放心
MySQL:完整性约束和 表的设计原则
Meishe Q&A Room | Meiying VS Meishe Cloud Editing
低代码是开发的未来吗?浅谈低代码开发平台的发展现状及未来趋势
Win11 file types, how to change?Win11 modify the file suffix
C#/VB.NET:在 Word 中设置文本对齐方式
用匿名函数定义函数_c语言最先执行的函数是
CompletableFuture接口核心方法介绍
【机器学习】:如何对你的数据进行分类?