记一次MySQL字符串索引优化方案

记一次MySQL字符串索引优化方案本文已收录GitHub,更有互联网大厂面试真题,面试攻略,高效学习资料等字符串建立索引的优化1.建立前缀索引假设建立一个支持邮箱登录的用户表,对于邮件字段来说,可以有以下几种建立索引的方式:①.直接…

	记一次MySQL字符串索引优化方案[数据库教程]

本文已收录GitHub,更有互联网大厂面试真题,面试攻略,高效学习资料等

字符串建立索引的优化

1. 建立前缀索引

假设建立一个支持邮箱登录的用户表,对于邮件字段来说,可以有以下几种建立索引的方式:

①. 直接对整个字符串建立索引

alter table SUser add index index1(email);

代码100分

②. 对整个字符串的前一部分建立索引 – 前缀索引

代码100分alter table SUser add index index2(email(6));

方式 2 相较于 方式 1 来说,利用前缀索引,占用的空间更小。但有可能造成性能的损失,读取数据的次数变多。

假设在 user 表中存在[email protected], [email protected] , [email protected], 三条记录。

有这样一条语句 select id,name,email from SUser where email=‘[email protected]‘;

使用 index1 索引时,流程如下:

  1. 在 index1 中,找到名字是[email protected] 的记录,获取 ID.
  2. 在主键索引上对应 ID的行,判断 email 是否正确,将记录加入结果集。
  3. 接着取 index1 索引的下一条记录,发现不满足 email 格式,结束循环。

使用 index2 索引:

  1. 在 index2 中,找到名字是 zhangs 的记录,获取 ID.
  2. 在主键索引上对应 ID的行,这时拿到的是 [email protected] 的行, 发现不符合,丢弃。
  3. 接着在 index2 循环,拿到下一条记录 ID。
  4. 在主键索引上对应 ID的行,这时拿到的是 [email protected] 的行, 发现不符合,丢弃。
  5. 接着在 index2 循环,拿到下一条记录 ID。
  6. 在主键索引上对应 ID的行,这时拿到的是[email protected] 的行, 发现符合,纳入结果集。
  7. 接着在 index2 循环,发现记录格式不符合,结束循环。

看这个过程,很容易发现,前缀索引会增加查询语句读取数据的次数。

但如果将前缀索引的 email(6) 改成 email(7),就会减少查询的次数,对应在主键索引上只搜索一次。这就说明,如果能合适的设置前缀索引的长度,就能在空间和效率上取得平衡。

如何找到合适的前缀索引长度

在建立索引时,应该去关注区分度,区分度越高,则说明重复的键值越少。

可以通过执行查询来统计列上有多少不同的值。

mysql> select 
  count(distinct email)as L,
  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%, 用 L 的数量 * 区分度比例(1-5%=95%),然后看在 L4 到 L7 中哪个满足。

前缀索引的影响

在之前覆盖索引的文章中,如果查询的列的信息被包含在二级索引上,那么就可以避免回表的过程,进而减少查询次数,提供效率。但如果在建立索引时,使用了前缀索引,那么无论满不满足覆盖索引的规则,都会回表。因为系统不能确定前缀索引是否截取了完成信息,进而必须做一次判断。

也就是说,前缀索引除了会增加查询语句的次数,还会禁止使用覆盖索引

2. 倒序存储

对于邮箱这类的字符串来说,由于前几位有较大的区分度,所以用前缀索引还不错。但如果是区分度不好的情况,比如身份证,前 6 位都是地址码,很多人都会一样。这时如果想要使用前缀索引,就需要至少 12 位以上,对应查询效率和空间都不是很合适。

一个比较好的办法是将字符串倒序存储,将区分度高的字符开头。

例如:

代码100分mysql> select field_list from t where id_card = reverse(‘input_id_card_string‘);

3. 使用 hash 字段

在网络传输时,CRC – 循环冗余校验被用于检验文件。对应在 MySQL 里也有这个函数,crc32().

该函数的返回范围是 0-4294967296 也就是 4 字节,相对于其他字符串来说,属于较短的长度。

在创建表时,可再创建一个整数字段,来保存这类字符串,如身份证的校验码(crc32()的返回值), 并为该字段创建索引。

如:

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

在插入记录时,将 crc32() 的结果插入到记录中。

但由于 crc32() 只有 32 位的特性,容易发生 hash 碰撞,就是说可能两个字符串经过计算后得到相同的验证码。这时就存在冲突,所以还需要判断下查询的值是否一致。

如:

mysql> select field_list from t where id_card_crc=crc32(‘input_id_card_string‘) and id_card=‘input_id_card_string‘

总结

我们知道,MySQL 中使用的是 B+ 树来存储索引的,这自然就是有序的,所以前缀查询就支持范围查询。

而 Hash 字段和倒序查询两种方式就不行了,倒序查询是按照倒序字符串存储的,而 hash 字段和字符串本身也没有关系,这就意味着这两种方式是不支持范围查询的。

在占用空间上来说,倒序存储占用的是和普通索引的一样的空间。而 hash 字段,需要增加一个字段来存在 hash 校验码。

在 CPU 消耗,倒序时,每次读和写都需要调用 reverse 函数。hash 方式需要额外调用 crc32() 函数。两个函数实现来看,reverse 函数 CPU 消耗会少些。

在查询效率上,hash 字段查询性能更好稳定些。虽然可能存在冲突的情况,但概率很小。而倒序存储还是用前缀索引的方式,会额外增加扫描行数。

总结一下,一般提高查询字符串的效率有如下方式:

  • 直接创建完成索引,但占用空间较大。
  • 创建前缀索引,节省空间,但会增加扫描次数,不能利用覆盖索引。
  • 倒序存储,再创建前缀索引,节省空间,增加扫描次数,不能利用覆盖索引。
  • hash 字段,性能稳定,但占用额外的空间,不支持范围查询。

记一次MySQL字符串索引优化方案

原文地址:https://blog.51cto.com/14637764/2510953

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/7383.html

(0)
上一篇 2023-03-21 10:30
下一篇 2023-03-21 11:30

相关推荐

  • MySQL存储过程实现表内数据查询结果批量插入[亲测有效]

    MySQL存储过程实现表内数据查询结果批量插入[亲测有效]1、场景 为菜单表中所以机构(organization_id唯一标识)课程项目(一级菜单)菜单下新增图书管理子菜单并为所有机构增加该子菜单的绑定关系。具体查询步骤: (1)查询菜单表中有菜单配置的所…

    2023-02-08
    141
  • 使用Python判断素数

    使用Python判断素数素数是指在大于1的自然数中,除了1和本身以外,不能被其他自然数整除的数。判断一个数字是否为素数一直是计算机编程领域中一个很热门的话题。Python 作为一门强大且易学的编程语言,提供了多种方法用于判断素数。本文将介绍多种 Python 算法来判断一个数字是否是素数。

    2024-07-29
    28
  • sql中的事务是什么意思_数据库事务有acid属性

    sql中的事务是什么意思_数据库事务有acid属性概述: 事务是由一系列语句构成的逻辑工作单元。事务和存储过程等批处理有一定程度上的相似之处, 通常都是为了完成一定业务逻辑而将一条或者多条语句“封装”起来,使它们与其他语句之间出现一个逻辑上的边界,并

    2022-12-30
    146
  • 03.事务隔离「建议收藏」

    03.事务隔离「建议收藏」简单来说,事务就是要保证一级数据库操作,要么全部成功,要么全部失败。在MySQL中,事务支持是在引擎层实现的,但MySQL中并不是所有引擎都支持事务,比如Mysql原生的MyISAM引擎就不支持事务…

    2022-12-25
    145
  • Sql Server一个表向另一个表添加多条数据,关联时查询出一条数据[通俗易懂]

    Sql Server一个表向另一个表添加多条数据,关联时查询出一条数据[通俗易懂]废话不多说 !!! 我的需求是这样的,一条信息可以有多个部门验收,当所有的部门验收完成之后呢,才把最后验收的那条数据显示出来。 直接看表结构 以上就是三张表分别查询出来的数据,注意标红的地方才是重点。

    2023-04-27
    154
  • Python词频统计代码

    Python词频统计代码在大量文本数据中,关键词的频次统计往往是必不可少的。无论是从市场营销角度还是从学术角度,词频统计都占有重要的地位。而Python作为一种擅长文本处理的编程语言,提供了一种快速而准确的词频统计方法。

    2024-06-29
    44
  • CentOS7安装Elasticsearch7.6.2「建议收藏」

    CentOS7安装Elasticsearch7.6.2「建议收藏」最近登录到Elasticsearch官网发现Elasticsearch已经更新到7.8的版本了,但是自己公司使用的还是6.4版本,查了下,发现7.X的版本与6.X的版本差别还挺大的,所以准备在自己的个

    2023-03-28
    168
  • python搜索关键词_python检索

    python搜索关键词_python检索如何采集关键词检索结果,今天前嗅大数据就以古诗文网为例为大家演示,话不多说一起看看吧。 一. 网站内容 1. 网站截图说明 本教程通过“古诗文网”官网来采集所需“关键词”的正文数据,本教程以关键词“…

    2022-12-27
    143

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注