mysql(三)InnoDB之自适应hash索引

news2024/10/6 14:26:04

目录

  • 前言
  • 自适应哈希索引 (Adaptive Hash Index, AHI)
    • 既然是哈希,key 是什么,value 是什么?
    • 为啥叫 “自适应 (adaptive)****” 哈希索引?
    • 系统会不会判断失误,是不是一定能加速?
  • 创建自定义的hash索引
    • 思路
    • 示例
      • 如何处理hash冲突

前言

InnoDB 用户无法手动创建哈希索引,如果从这一层面来说,InnoDB 不支持哈希索引,但是InnoDB 会自调优 (self-tuning),如果判定建立自适应哈希索引 (Adaptive Hash Index, AHI),能够提升查询效率,InnoDB 自己会建立相关哈希索引,如果从这一层来说,InnoDB 是支持哈希索引的

自适应哈希索引 (Adaptive Hash Index, AHI)

新建一张表

CREATE TABLE `user`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NULL,
  `sex` char(4) NULL,
  `flag` char(4) NULL,
  PRIMARY KEY (`id`),
  INDEX `name`(`name`) USING BTREE
);

id 是主键,name 建了普通索引。

在表中插入四条记录:

  • 1, shenjian, m, A

  • 3, zhangsan, m, A

  • 5, lisi, m, A

  • 9, wangwu, f, B

在这里插入图片描述
如上图,通过前序知识,容易知道 InnoDB 在主键 id 上会建立聚集索引 (Clustered Index),叶子存储记录本身,在 name 上会建立普通索引 (Secondary Index),叶子存储主键值。

发起主键 id 查询时,能够通过聚集索引,直接定位到行记录。
在这里插入图片描述

select * from t where name='ls'

发起普通索引查询时:

  1. 会先从普通索引查询出主键(上图右边);

  2. 再由主键,从聚集索引上二次遍历定位到记录(上图左边)。

不管聚集索引还是普通索引,记录定位的寻路路径 (Search Path) 都很长。

在 MySQL 运行的过程中,如果 InnoDB 发现,有很多 SQL 存在这类很长的寻路,并且有很多 SQL 会命中相同的页面 (page),InnoDB 会在自己的内存缓冲区 (Buffer) 里,开辟一块区域,建立自适应哈希所有 AHI,以加速查询。
在这里插入图片描述
从这个层面上来说,InnoDB 的自使用哈希索引,更像 “索引的索引”,毕竟其目的是为了加速索引寻路。

既然是哈希,key 是什么,value 是什么?

key 是索引键值(或者键值前缀),value 是索引记录页面位置。

为啥叫 “自适应 (adaptive)****” 哈希索引?

系统自己判断 “应该可以加速查询” 而建立的,不需要用户手动建立,故称“自适应”。

系统会不会判断失误,是不是一定能加速?

不是一定能加速,有时候会误判。

当业务场景为下面几种情况时:

  • 很多单行记录查询(例如 passport,用户中心等业务)
  • 索引范围查询(此时 AHI 可以快速定位首行记录)
  • 所有记录内存能放得下

AHI 往往是有效的。当业务有大量 like 或者 join,AHI 的维护反而可能成为负担,降低系统效率,此时可以手动关闭 AHI 功能

创建自定义的hash索引

如果存储引擎不支持hash索引,则可以模拟像InnoDB一样创建hash索引,这样可以得到hash索引带来的便利,如只需要 很小的索引就可以为超长的键创建索引

思路

在B-Tree的基础上创建一个伪hash索引,这和真正的hash索引不是一回事,因为还是使用B-Tree进行查找,但是它使用hash值而不是键本身进行索引查找。我们需要做的就是在查询的WHERE字句中手动指定使用hash函数

示例

此时我么新建一张表,需要存储大量的URL,并且根据URL进行搜索查找。如果使用B-tree来存储URL,存储的内容就会很大,因为URL本身都很长。

新建一张表

create table pseudohash(
id int UNSIGNED not null auto_increment,
url VARCHAR(255) not null,
url_crc int UNSIGNED not null DEFAULT 0,
PRIMARY KEY(id)
) 

然后创建触发器

CREATE TRIGGER pseudohash_crc_ins BEFORE INSERT ON pseudohash FOR EACH ROW
BEGIN	
	SET NEW.url_crc = CRC32(
	NEW.url);
	end;
	
	
CREATE TRIGGER pseudohash_crc_upd BEFORE UPDATE ON pseudohash FOR EACH ROW
BEGIN	
	SET NEW.url_crc = CRC32(
	NEW.url);
	end;

插入数据
在这里插入图片描述

一般情况,是在url建索引查询

select id from pseudohash where url ='www.baidu.com123217'

但是我们删除了url上面的索引,对url_crc使用CRC32做hash,就可以使用下面的方式进行查询

select id from pseudohash where url='www.baidu.com123217' and url_crc = CRC32('www.baidu.com123217')

这样做的性能就会很高,因为MySQL优化器会使用这个选择性很高而体积很小的基于url_crc列的索引来完成查找。即使有多个记录有相同的索引值,朝招仍然很快,只需要根据hash值做快速的整数比较就能找到索引条目,然后一一比较返回对应的行。但是这样实现的缺陷就是需要维护hash值。可以手动维护,也可选择使用触发器

如果采用这种方式,最好不要使用SHA1()和MD5()作为hash函数。因为这两个函数计算出来的hash值是非常长的字符串,会浪费大量空间,比较时也会更慢。SHA1()和MD5()是强加密函数,设计的目标是最大限度的消除冲突,但这里并不需要这样高德要求。简单的hash函数的冲突在一个可以接受的范围,同时又能提供更好的性能。

如果表非常大,CRC32()会出现大量的hash冲突,则可以考虑自己实现一个简单的64位hash函数

如何处理hash冲突

查询的时候,必须得是如下

select id from pseudohash where url='www.baidu.com123217' and url_crc = CRC32('www.baidu.com123217')

仅仅是如下的查询

select id from pseudohash where  url_crc = CRC32('www.baidu.com123217')

当发生hash冲突的时候,是无法正确工作的

参考:

https://zhuanlan.zhihu.com/p/339957841

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

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

相关文章

华为申请注册盘古大模型商标;京东推出言犀大模型,率先布局产业应用

7月14日科技新闻早知道,一分钟速览。 1.华为申请注册盘古大模型商标: 据天眼查 App 显示,7 月 7 日,华为技术有限公司申请注册“华为云盘古”、“Huawei Cloud Pangu Models”文字及图形商标,国际分类为网站服务、社…

基础设施SIG月度动态:龙蜥官网新增CSDN第三方账号登录,内核CI新增测试任务停止功能

基础设施 SIG(OpenAnolis Infra SIG)目标:负责 OpenAnolis 社区基础设施工程平台的建设,包括官网、Bugzilla、Maillist、ABS、ANAS、CI 门禁以及社区 DevOps 相关的研发工程系统。 01 SIG 整体进展 1. 龙蜥社区官网与 CSDN dev…

管理大规模文件的挑战与解决方案

管理大规模文件是当今企业和组织面临的一项重要挑战。随着信息技术的迅速发展和数字化转型的推进,组织内外产生的文件数量呈指数级增长,如何高效地管理这些文件成为了亟待使用文件管理系统解决的问题。 挑战一:数据量巨大 随着企业和组织的…

基于STM32CUBEMX驱动TOF模块VL6180与VL6180X(5)----驱动多个VL6180X

基于STM32CUBEMX驱动TOF模块VL6180与VL6180X----5.驱动多个VL6180X 概述样品申请修改设备地址配置vl6180x主程序测试结果 概述 在本章中,我们将探讨如何同时驱动多个VL6180传感器进行距离测量。我们将介绍如何有效地管理多个传感器之间的通信和控制,以确…

❤️创意网页:创造精彩的登录体验-3D翻转登录页面

✨博主:命运之光 🌸专栏:Python星辰秘典 🐳专栏:web开发(简单好用又好看) ❤️专栏:Java经典程序设计 ☀️博主的其他文章:点击进入博主的主页 前言:欢迎踏入…

(9)基础强化:元字符,正则表达式,匹配,提取组,Regex,Match与Matches

一、作业 1、问:下面解压程序出错,什么原因? string src "E:\1.txt";string des "E:\2.txt";using (FileStream read File.OpenRead(src)){using (GZipStream gzip new GZipStream(read, CompressionMode.Decompress…

FPGA——按键控制led灯

文章目录 一、实验环境二、实验任务三、系统设计四、实验过程4.1 编写verilog代码4.2 引脚配置 五、仿真5.1 仿真代码5.2 仿真结果 六、实验结果七、总结 一、实验环境 quartus 18.1 modelsim vscode Cyclone IV开发板 二、实验任务 使用开发板上的四个按键控制四个LED灯。按…

“反AI斗士”马斯克进军AI,你怎么看?

“反AI斗士”马斯克进军AI,你怎么看? 当地时间7月12日,马斯克在Twitter上宣布:“xAI正式成立,去了解现实。”马斯克表示,推出xAI的原因是想要“了解宇宙的真实本质”。公司由马斯克本人亲自带队&#xff0c…

软件外包开发的原型图工具

在软件开发中需要用到原型图工具来将需求转化为图形界面,这样可以更好更准确的表达需求的实现方式。与传统的需求文档相比,原型图的表达更直接,不但可以画出UI,也支持UI之间的跳转连接,与最终的实现效果基本是一样的。…

【雕爷学编程】Arduino动手做(149)---MAX9814咪头传感器模块4

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&am…

如何在Windows 8和10中检查最后一次的启动模式

Windows 8、Windows 8.1 和 Windows 10 中的用户可以在 PC 上执行混合关机(快速启动)、完全关机或休眠。 快速启动(又名:hiberboot、混合启动或混合关机)在 Windows 中默认打开,是一种帮助你的电脑在关机后更快启动的设置。甚至比休眠还要快。 休眠是一种主要为笔记本电…

Linux下Nginx升级

nginx版本升级不会覆盖配置文件,但以防万一升级前请先备份配置文件或者配置文件夹 默认配置文件地址:/usr/local/nginx/conf/nginx.conf 1.下载 wget -c http://nginx.org/download/nginx-1.24.0.tar.gz 2.解压 tar -xvf nginx-1.24.0.tar.gz 3.nginx…

【图像处理】使用 Python 进行图像增强

一、说明 图像增强技术的深度和复杂性往往在一系列捕获和共享中被忽视。从傅里叶变换到白平衡和直方图处理,各种方法都可以将普通照片转换为引人注目的图像。这篇博文旨在解开这些技术。 我在节日期间拍了一张照片,在夜间庆祝活动中。遗憾的是&#xff0…

OpenCV中掩膜(Mask)、setTo()、copyTo()、clone()、inRange()的定义与使用

文章目录 1、掩膜(Mask)是什么(1)从物理的角度来看:(2)图像处理中的掩膜Mask(3)掩膜的用法:(4)掩膜Mask 的运算: 2、setTo()函数:将图…

【动手学习深度学习--逐行代码解析合集】17使用块的网络(VGG)

【动手学习深度学习】逐行代码解析合集 17使用块的网络(VGG) 视频链接:动手学习深度学习–使用块的网络(VGG) 课程主页:https://courses.d2l.ai/zh-v2/ 教材:https://zh-v2.d2l.ai/ 1、VGG网络…

【UniApp开发小程序】顶部导航栏和底部导航栏设置+iconfont图标引入

文章目录 顶部导航栏和底部导航栏设置创建几个需要底部导航栏切换的页面使用阿里巴巴矢量图标库完成底部导航栏tabBar设置页面顶部导航栏标题 样式优化 顶部导航栏和底部导航栏设置 在正式开发小程序的功能之前,首先需要确定小程序的主要框架。 创建几个需要底部导…

组件的创建,引用,样式隔离以及methods,data,properties和数据事件监听

组件的创建,引用,样式隔离以及methods,data,properties和数据事件监听 1. 组件的创建2. 组件的引用2.1. 局部引用2.2. 全局引用2.3. 组件和页面的区别 3. 组件的样式隔离3.1. 默认情况,组件样式隔离性3.2. 修改组件的样式隔离选项 4. 组件的d…

短视频抖音seo矩阵系统源码开发者思路(一)

一套优秀的短视频获客系统,支持短视频智能剪辑、短视频定时发布,短视频排名查询及优化,短视频智能客服等,那么短视频seo系统具体开发应该具备哪些功能呢?今天小编就跟大家分享一下我们的技术开发思路。 抖音矩阵系统源…

go-zero微服务实战——etcd服务注册与发现

etcd简介 浅谈etcd服务注册与发现 etcd官网 etcd中文文档 apt安装etcd,启动命令十分简单etcd。 etcd分为v2版本和v3版本,命令有所不一样,使用命令etcdctl h查看 如上图所示并没有出现API的版本,此时是使用默认的v2版本&#x…

android editText获取不到数据

问题分析:在onActivityCreated一开始就创建了findViewById,这时获取的是默认值,需要在点击按钮时重新加载才能获取到输入数据。 需要在点击按钮时重新加载数据: