MySQL中给字符串字段加索引

news2024/11/29 4:02:01

文章目录

  • 前言
  • 一、前缀索引和普通索引
  • 二、前缀索引对覆盖索引的影响
  • 三、优化前缀索引


前言

学完了MySQL索引部分,我们清楚的认识到给子段添加索引可以快速的进行查询,节约时间。但是索引有很多。那么对于字段怎么加索引,加什么索引。加到索引不同,效率肯定也会有不同的。接下来,我们研究下,怎么给字符串字段加索引


一、前缀索引和普通索引

我们依旧是通过一个例子进行讲解。

我们用邮箱登录这个业务。创建了一个用户表,SQL句如下:

create table SUser(
	ID bigint unsigned primary key,
	email varchar(64),
	...
	)engine=InnoDB;

要是有邮箱登录,业务代码中一定会出现如下这样的SQL语句:

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

对于这查询语句,相比加上索引效率效率更高。
但是加上什么索引呢?
如果只是普通的加上索引,那么相应的索引对应的B+树中存储的就这email索引列的全部内容。想必都知道,一个邮箱账号包含的字符串是很长。如果把这一个很长的字符串充当索引,那是很浪费存储空间的。为此,我们可以使用前面提到过前缀索引,即把email的一部分字符串设置为索引。接下来,我们分析学习下两者的效率。

针对email字段创建如下两个不同的索引,进行分析:

alter table SUser add index index1(email);
或者
alter table SUser add index index2(email(6));

第一个语句创建的index1索引里面,包含了每个记录的整个字符串;而第二个语句创建的index2
索引里面,对于每个记录都是只取前6个字节。

针对这两个的存储,存储结构图,如下所示:
对index1:
在这里插入图片描述
对index2:
在这里插入图片描述
从图中的存储可以看出,email(6)这个存储占用的空间更小。这是使用前缀索引的优势,但是查询效率上呢,接下来我们分析一下。

执行下面的SQL语句,看看不同的索引执行流程有何不同:

select id,name,email from SUser where email='zhangssa@xxx.com';

如果使用的是index1(即email整个字符串的索引结构),执行顺序是这样的:

  • 从index1索引树找到满足索引值的这条记录,取得ID2的值;
  • 到主键上查到主键值是ID2的行,判断email的值是正确的,将这行记录加入结果集;
  • 取index1索引树上刚刚查到的位置的下一条记录,发现已经不满足条件了,循环结束。

这个过程中,只需要回主键索引取一次数据,所以系统认为只扫描了一行。

如果使用的是index2 (即email(6)索引结构),执行顺序是这样的:

  • 从index2索引树找到满足索引值是’zhangs’的记录,找到的第一个是ID1;
  • 到主键上查到主键值是ID1的行,判断出email的值不是这行记录丢弃;
  • 取index2上刚刚查到的位置的下一条记录,发现仍然是’zhangs’,取出ID2,再到ID索引上取整行然后判断,这次值对了,将这行记录加入结果集;
  • 重复上一步,直到在idxe2上取到的值不是’zhangs’时,循环结束。

通过这个对比,你很容易就可以发现,使用前缀索引后,可能会导致查询语句读数据的次数变多。

通过看使用前缀索引结构,进行检索。如果设置的前缀个数较少,那各个字段的区分度不大,就会有很多重合的索引,就需要多次回表进行检查。区分度越高越好。因为区分度越高,意味着重复的键值越少。但是要存储的字符串就会越多,所以要平衡下,找到最好的前缀索引。

二、前缀索引对覆盖索引的影响

我们将上面的SQL查询语句,变成下面的:

select id,email from SUser where email='zhansss%@xxx.com';

如果使用index1(即email整个字符串的索引结构)的话,可以利用覆盖索引,从index1查
到结果后直接就返回了,不需要回到ID索引再去查一次。而如果使用index2(即email(6)索引结
构)的话,就不得不回到ID索引再去判断email字段的值。

将index2的定义修改为email(18)的前缀索引,这时候虽然index2已经包含了所有的信息,但InnoDB还是要回到id索引再查一下,因为系统并不确定前缀索引的定义是否截断了完整信

也就是说,使用前缀索引就用不上覆盖索引对查询性能的优化了,这也是你在选择是否使用前缀
索引时需要考虑的一个因素。

对前缀索引方式的优化

三、优化前缀索引

对于邮箱这样的使用前缀比较合适,但是如果像身份证这样的,因为身份证前很多位都是表示地理信息的,所以每个人的区分度不大。

为了解决这个区分度的问题,设计了如下两种方法:

第一种方式:倒序存储
存储身份证号的时候把它倒过来存,每次查询的时候,可以这么写:

select field_list from t where id_card=reverse('input_id_card_string');

第二种方式:使用hash字段
在表上再创建一个整数字段,来保存身份证的校验码,同时在这个字段上创建索引:

alter table t add id_card_crc int unsigned, add index(id_card_crc);

每次插入新记录的时候,都同时用crc32()这个函数得到校验码填到这个新字段。由于校验码可能存在冲突,也就是说两个不同的身份证号通过crc32()函数得到的结果可能是相同的,所以你的查询语句where部分要判断id_card的值是否精确相同。

它们这两个都不支持范围查询。倒序存储的字段上创建的索引是按照倒序字符串的方式排序的,已经没有办法利用索引方式查出身份证号码在[ID_X, ID_Y]的所有市民了。同样
地,hash字段的方式也只能支持等值查询

键值越少。

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

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

相关文章

linux基本功系列之useradd命令实战

文章目录一. useradd 命令介绍二. 语法格式及常用选项三. 参考案例3.1 不加任何参数创建用户3.2 创建不能登录系统且没有家目录的用户3.3 创建一个用户,ID为23333.4 创建一个用户并指定其附加组3.5 创建用户并账户过期时间3.6 与useradd相关的目录文件总结前言&…

InfluxDB的查询优化

首先,在学习influxDB的查询优化之前,我们要先学习下InfluxDB的解释器profiler(类似于mysql的Explain语句,不一样的是,sql,hivesql是提前查看执行计划等,Influx是在当前查询的最后一页两张表&…

力扣(LeetCode)382. 链表随机节点(2023.01.15)

给你一个单链表,随机选择链表的一个节点,并返回相应的节点值。每个节点 被选中的概率一样 。 实现 Solution 类: Solution(ListNode head) 使用整数数组初始化对象。 int getRandom() 从链表中随机选择一个节点并返回该节点的值。链表中所有…

WhatsApp居然有3个版本?深度详解区别!外贸圈获客神器用起来!

近两年,外贸圈用WhatsApp来营销获客,越来越火。不少走在前头的外贸人,已经尝到了甜头。但也有不少后来者,站在门外张望的时候,整个人都是蒙圈的。❓听说动不动要整几十个账号,还要花老长时间养号&#xff1…

《Linux Shell脚本攻略》学习笔记-第六章

6.1 简介 你开发应用程序的时间越长,就越能体会到有一个能够跟踪程序修订历史的软件是多重要。 大多数Linux发行版中都包含了Git。如果你的系统中还没有安装,可以通过yum或者apt-get获取。 6.2 创建新的git仓库 git中的所有项目都需要有一个用于保存项目…

MyBatis-Plus字段加密解密

项目创建POM依赖 <dependency><!--MyBatis-Plus 企业级模块--><groupId>com.baomidou</groupId><artifactId>mybatis-mate-starter</artifactId><version>1.2.8</version> </dependency> <!-- https://mvnrepository…

规划之路:SLAM学习经验分享

针对想学SLAM的提问&#xff0c;我觉得我还是有一定的发言权。作为一个刚入坑SLAM一年多的初学者&#xff0c;首先想说的就是这个研究方向比较广&#xff0c;大方向按搭载传感器分为激光SLAM和视觉SLAM两种&#xff0c;激光SLAM搭载激光雷达&#xff0c;视觉SLAM搭载单目、双目…

[NSSRound#6 Team]Web学习

[NSSRound#6 Team]Web学习 文章目录[NSSRound#6 Team]Web学习前言一、[NSSRound#6 Team]check(V1)二、[NSSRound#6 Team]check(Revenge)总结前言 日常做点题娱乐下&#xff0c;刷到了[NSSRound#6 Team]中是三道web题&#xff0c;学习到了不少&#xff0c;记录下知识点。 提示&…

C语言综合练习6:制作贪吃蛇

1 初始化界面 因为还没学QT&#xff0c;我们就使用终端界面替代。 这里我们假设界面中没有障碍物&#xff0c;我们只需要设定界面的高宽就行&#xff0c;这是蛇的移动范围&#xff0c;我们可以写两个宏来规定界面的高宽 新建一个snake.c的文件 #define _CRT_SECURE_NO_WARNIN…

快出数量级的性能是怎样炼成的

前言&#xff1a;今天学长跟大家讲讲《快出数量级的性能是怎样炼成的》&#xff0c;废话不多说&#xff0c;直接上干货~我们之前做过一些性能优化的案例&#xff0c;不算很多&#xff0c;还没有失手过。少则提速数倍&#xff0c;多则数十倍&#xff0c;极端情况还有提速上千倍的…

关于IDEA配置本地tomcat部署项目找不到项目工件的问题解答

文章目录一 原因分析二 解决方案三 具体的操作方法3.1 打开项目结构找到工件3.2 添加具体的工件内容3.3 配置本地tomcat一 原因分析 可能是之前的项目再次打开后&#xff0c;没有及时配置项目结构中的工件信息&#xff0c;导致配置tomcat中看不到工件的信息 二 解决方案 解决…

react组件优化,当父组件数据变化与子组件无关时,控制子组件不重新渲染

首先 我们来建立一个场景 我们创建一个react项目 然后创建一个父组件 这里我要叫 record.jsx 参考代码如下 import React from "react"; import Subset from "./subset";export default class record extends React.Component{constructor(props){super(…

工作的同时,我也在这里做副业

文章目录一、什么是独自开&#xff1f;二、独自开能给我们带来什么利益&#xff1f;三、如何使用独自开&#xff1f;3.1、用户任务报价步骤13.2、用户任务报价步骤2四、未来的愿景一、什么是独自开&#xff1f; 独自开&#xff0c;全称独自开发一套系统&#xff0c;是基于商品…

CTP开发(2)行情模块的开发

我在做CTP开发之前&#xff0c;也参考了不少其他的资料&#xff0c;发现他们都是把行情和交易做在同一个工程里的。我呢之前也做过期货相关的交易平台&#xff0c;感觉这种把行情和交易做在一起的方法缺乏可扩展性。比如我开了多个CTP账户&#xff0c;要同时交易&#xff0c;这…

springMVC的学习拦截器之验证用户登录案例

文章目录实现思路关于环境和配置文件pomspring的配置文件关于idea的通病/常见500错误的避坑实现步骤编写登陆页面编写Controller处理请求编写登录成功的页面编写登录拦截器实现思路 有一个登录页面&#xff0c;需要写一个controller访问页面登陆页面提供填写用户名和密码的表单…

UE4c++日记1(允许 创类、蓝图读写/调用/只读、分类、输出日志打印语句)

目录 1允许创建基于xx的蓝图类 2允许蓝图读写/允许蓝图调用/只读 读写调用 只读 3为变量/函数分类 4输出日志打印一段话 1.先创建一个蓝图类 2.构建对象 3.写提示代码&#xff0c;生成解决方案 4.运行&#xff0c;打开“输出日志” 5.总结 创类-实例化对象&#xff08;构建…

2022年个人年终总结(一)

2022年个人年终总结&#xff08;一&#xff09;考研想法的萌生回顾过去一年-考研心路历程基础阶段&#xff08;1-6月&#xff09;强化阶段&#xff08;7-9月&#xff09;冲刺阶段&#xff08;10-12月&#xff09;感受总结特别感谢2022年是做梦的一年&#xff0c;花了一年的时间…

Zookeeper相关操作

Zookeeper概念 •Zookeeper 是 Apache Hadoop 项目下的一个子项目&#xff0c;是一个树形目录服务。 •Zookeeper 翻译过来就是 动物园管理员&#xff0c;他是用来管 Hadoop&#xff08;大象&#xff09;、Hive(蜜蜂)、Pig(小 猪)的管理员。简称zk •Zookeeper 是一个分布式的…

【C++】非递归实现二叉树的前中后序遍历

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《吃透西嘎嘎》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;二叉树的…

如何运营个人技术博客

前言 本篇和大家聊聊如何运营个人技术博客&#xff0c;定位下做技术写作的目的&#xff0c;有哪些交流平台和输出方式&#xff0c;如何把控内容质量&#xff0c;整理了一些写作技巧和自己常用的写作工具&#xff0c;最后分享下如何在有限的时间里合理安排保证写作与工作的平衡。…