如何给字符串字段加索引?

news2025/1/13 6:03:18

1.引例

现在的系统中,很多都会包含邮箱字段,那要如何给这个字段建立索引呢?

假设,现在维护了一个用户表,其中包含邮箱,定义如下:

mysql>
    create table SUser(
        ID int primary key,
        email varchar(64),
        ...
    )engine=InnoDB;

如果我们要根据邮箱查询用户信息,那必然会用到下面的语句:

mysql> select f1, f2 from SUser where email='xxx';

如果在email这个字段上没有索引,那么这个语句就只能做全表扫描。

你可以给字符串加索引,当不指定索引的长度的时候,索引就会包含整个字符串,如下面的语句和图所示:

alter table SUser add index index1(email)

在这里插入图片描述

由于MySQL支持前缀索引,所以可以将字符串的一部分作为索引,如下图的语句和图所示:

mysql> alter table SUser add index index2(eamil(6));

在这里插入图片描述

由此可见,这个索引只使用了邮箱字段的前6个字节,占用空间更小,这就是前缀索引的优势。

接着,我们来看下这个语句,在两种索引下是如何执行的:

mysql> select id, name, email from SUser where email="zhangssxtz@xxx.com"

如果使用的是index1(整个字符串索引),则查询流程是:

  1. 从index1的索引树上查到"zhangssxtz@xxx.com",然后进行回表查询,判断email值是否正确,加入结果集
  2. 取index1索引树上的下一条记录,发现不满足了,就结束循环

可见,需要进行一次回表查询。

如果使用的是index2(email(6)索引),则查询流程是:

  1. 从index2的索引树上,涨到第一个满足前缀的"zhangs"的记录,进行回表查询,发现不匹配,这一行就丢弃。
  2. 取index2索引树上的下一条记录,发现仍然满足前缀"zhangs",进行回表查询,发现匹配,加入结果集。
  3. 继续重复上面的过程,直到不匹配

可见,需要进行四次回表查询。

因此,可以发现,有时候使用了前缀索引,反而导致查询语句读数据的次数变多。

但是容易发现,如果前缀索引的长度变为7,即"zhangss",则在索引树上只有一条记录满足,则只需要进行一次回表查询。

因此,使用前缀索引,长度很重要,既可以节省空间,又可以减少查询成本。我们在建立索引的时候,要关注区分度,区分度越高,意味着重复键值越少。

2.前缀索引对覆盖索引的影响

我们来看下面这个sql语句:

mysql>select id,email from SUser where email='zhangssxtz@xxx.com'

如果使用的是index1(整个字符串索引),那么就可以利用覆盖索引,直接返回结果了,不需要回表查询。

如果使用的是index2(email(6)索引),则需要回表查询email的值。

因此,如果使用前缀索引,那就用不上覆盖索引的优化了。

3. 其他方式

如果字符串区分度太低导致前缀区分的方式不好呢,还有什么方式。

例如当我们存储身份证号码的时候,同一个县的人,前6位都是一样的,那使用长度为6的前缀索引,需要回表的次数就很多。那如果使用长度为12的前缀索引,占有的磁盘空间又太大。

基于此,我们可以考虑下面两种方式,平衡这两者:

第一种方式是使用倒序存储,把身份证倒过来存储,查询的时候可以这样查询:

mysql> select field_list from t where id_card = reverse('input_id_car');

由于身份证后6位各不相同,就能够有很好的区分度。

第二种方式是使用hash字段,在表中再创建一个字段,使用hash函数对身份真进行计算,并存储到这个字段中。并且在这个hash字段建立索引。查询的时候可以这样写:

mysql>select field_list from t where id_card_hash=hash('input_id_card') and id_card = 'input_id_car';

这样就可以通过hash函数先筛选掉一部分,减少查询的次数。并且hash字段的长度也比身份证小很多。

最后,我们来比较两种方法的异同:

  1. 从占用空间看,倒序索引不需要消耗额外空间。hash字段只需要增加一个字段,但是也不用太长。
  2. 从CPU消耗看,倒序索引使用反转函数,比hash函数消耗小一些
  3. 从查询效率看,hash字段虽然会有冲突,但是概率会比倒序索引小一些。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/93.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenGL之多边形偏移、雾效、纹理映射

1.1 OpenGL中可以设置物体的点、线、面绘制模式。如果需要同时绘制多种模式,如下以面和线模式绘制两遍模型,可以看到线不连续,当镜头推远推近时会出现闪烁现象。 void glPolygonMode(GLenum face,GLenum mode);face :GL_FRONT,GL…

分治暴力求解最近点对问题 + 时间性能量化分析

Catalogue1 Intro2 Problem3 Time performance analysis4 Solution5 Reference1 Intro 本文旨在讨论分治和暴力在求解最近点对问题时的时间性能问题,关于解题部分不做过多讲解,只附上相关代码。 2 Problem 给定平面上N个点,找出其中的一对…

【Linux】第七章 进程控制(进程创建+进程终止+进程等待+进程替换+min_shell)

🏆个人主页:企鹅不叫的博客 ​ 🌈专栏 C语言初阶和进阶C项目Leetcode刷题初阶数据结构与算法C初阶和进阶《深入理解计算机操作系统》《高质量C/C编程》Linux ⭐️ 博主码云gitee链接:代码仓库地址 ⚡若有帮助可以【关注点赞收藏】…

【路径规划-多式联运】基于遗传算法求解多式联运运输问题(考虑碳交易)附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 更多Matlab仿真内容点击👇 智能优化算法 …

字符串和编码那些事

一、字符编码 1. ASCII字符编码 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte) 由于计算机是美国人发明的&#…

【Apache Spark 】第 11 章使用 Apache Spark 管理、部署和扩展机器学习管道

🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃 🎁欢迎各位→点赞…

编程神器Copilot逐字抄袭他人代码?

自面世后就饱受争议的 GitHub Copilot 编程神器最近又遭遇舆论风暴。 日前,德州农工大学的一位计算机科学教授 Tim Davis 在推特上发文称, GitHub Copilot 在没有标注来源也没有 LGPL 许可的情况下,输出了大量应该受版权保护的代码。 Tim Davis 还发了自己和 GitHub Copil…

90后汕头返种水稻 国稻种芯·中国水稻会:广东新农人田保姆

90后汕头返种水稻 国稻种芯中国水稻会:广东新农人田保姆 南方日报 张伟炜 新闻中国采编网 中国新闻采编网 谋定研究中国智库网 中国农民丰收节国际贸易促进会 国稻种芯中国水稻节 中国三农智库网-功能性农业农业大健康大会报道:“5月稻谷病虫害防护非常…

机器学习(周志华)课后习题

第1章 绪论 1.1 表1.1若只包含编号1和4的两个样例,试给出相应的版本空间。 版本空间:与训练及一致的假设集合。 色泽青绿,根蒂*,敲声*; 色泽*,根蒂蜷缩,敲声*; 色泽*,根…

nuxt.js 进行项目重构-首页

nuxt.js 也是基于vue 的 那么就离不开组件化开发 我们按照组件结构来进行分析 navTop 页面的头部 通用组件 分隔了三个位置 适用于大多数头部 且预留插槽 <template><div class"nav-top"><div class"left"><slot name"left…

Spring5入门到实战------10、操作术语解释--Aspectj注解开发实例。AOP切面编程的实际应用

1、操作术语 1.1、连接点 类里面哪些方法可以被增强、这些方法被称为连接点。比如&#xff1a;用户控制层有登录、注册、修改密码、修改信息等方法。假如只有登录类和注册类可以被增强&#xff0c;登录和注册方法就称为连接点 1.2、切入点 实际被真正增强的方法&#xff0c…

C++ 【UVA488】Triangle Wave

&#x1f4cb; 个人简介 &#x1f496;大家好&#xff0c;我是2022年3月份新人榜排名第三的 ༺Blog༒Hacker༻ &#x1f389;支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4ac;格言&#xff1a;༺永做优质༒programmer༻ &#x1f4e3; 系列专栏&am…

Unity技术手册-编辑器基础入门万字大总结

往期文章分享点击跳转>《导航贴》- Unity手册&#xff0c;系统实战学习点击跳转>《导航贴》- Android手册&#xff0c;重温移动开发 本文约8千字&#xff0c;新手阅读需要20分钟&#xff0c;复习需要12分钟 【收藏随时查阅不再迷路】 &#x1f449;关于作者 众所周知&…

【C/C++】程序环境,探索程序的执行过程(习得无上内功《易筋经》的第一步)

目录1.程序的翻译环境和执行环境2.详解编译链接2.1翻译环境2.2编译本身也分为几个阶段预编译&#xff08;预处理&#xff09;编译汇编详解符号表形成符号表2.3.链接合并段表符号表的合并和重定位3.运行环境总结&#xff1a;1.程序的翻译环境和执行环境 在ANSIC&#xff08;标准…

LeetCode每日一题——1235. 规划兼职工作

LeetCode每日一题系列 题目&#xff1a;1235. 规划兼职工作 难度&#xff1a;困难 文章目录LeetCode每日一题系列题目示例思路题解题目 你打算利用空闲时间来做兼职工作赚些零花钱。 这里有 n 份兼职工作&#xff0c;每份工作预计从 startTime[i] 开始到 endTime[i] 结束&a…

1024程序员节|基于Springboot实现爱心捐赠管理系统

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容&#xff1a;Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 文末获取源码 项目编号&#xff1a;BS-XX-…

Mybatis-plus学习(基于版本3.0.5)

文章目录一.概念1.1 简介1.2 特性二.快速入门三.CRUD扩展3.1 Insert插入3.2 主键生成策略3.3 Update更新3.4 自动填充3.5 乐观锁3.6 查询操作3.7 删除操作3.8 性能分析插件&#xff08;新版本的Mybatis-plus已将此插件移除&#xff09;3.9 条件构造器3.10 代码生成器一.概念 1…

Transformer合集3

太多了 我都累了 这都第4了 这次先是关于他的小样本目标检测 , 用很少的训练示例检测新目标 小样本目标检测 论文地址&#xff1a; https://openaccess.thecvf.com/content/CVPR2022/papers/Han_Few-Shot_Object_Detection_With_Fully_Cross-Transformer_CVPR_2022_paper.…

docker安装influxdb及备份恢复

influxdb安装influxdb1&#xff0c;拉取镜像2&#xff0c;创建目录并进入到目录内3&#xff0c;创建influxdb容器服务4&#xff0c;访问&#xff1a;ip8086备份恢复influxdb数据准备1.1 创建用户&#xff0c;填入组织&#xff0c;桶信息1.2&#xff0c;给桶添加点数据1&#xf…

ansible部署lnmp架构

环境准备&#xff1a; 主机名IP服务系统ansible192.168.160.131ansibleCentOS-8.5nginx192.168.160.132nginxCentOS-8.5mysql192.168.160.137mysqlCentOS-8.5php192.168.160.139phpCentOS-8.5 1、生成私钥&#xff0c;对另外三台主机进行免密登入 [rootansible ~]# ssh-keyge…