首页 > 数据库 >MySQL-hash索引

MySQL-hash索引

时间:2023-06-18 11:04:30浏览次数:48  
标签:index hash name 索引 搜索 哈希 MySQL

1哈希索引原理

哈希索引原理其实就是hash表,搜索时间效率O(1),搜索效率好,也意味着磁盘IO花费少,mysql底层使用的是链式哈希表,结构如下,每一个bucket就是一个个哈希桶,也就是哈希链表的头结点。哈希结构天然的需要耗费空间资源,是一种用空间换时间的做法

2哈希要点:

  • 解决哈希冲突的几种方式
  • 再哈希的参数碰撞因子或者说负载因子

MySQL-hash索引_搜索

说白了就是用的拉链法去解决的哈希冲突,也正是这个结构造成了哈希索引的一些特性

  • 哈希表没有顺序可言,只能进行等值查询,不支持范围搜索
  • 哈希表不稳定,效率最差可能变为O(n),因为哈希冲突链表可能会变长
  • 天然不能减少磁盘IO,要基于内存
  • 会锁住桶,有可能造成阻塞

3创建哈希索引sql语句如下

create index nameidx on student(name) using hash;

提示一下即使创建的是hash索引,也不一定就是哈希结构,Mysql会自动优化,具体用的是什么索引还是需要看看的,依然有可能使用的还是BTREE索引

show indexes from student;

4自适应哈希索引

自适应哈希索引作用:MySQL Server为避免频繁回表,会使用频繁访问的二级索引项创建哈希索引

假如name是有索引的,我们不断使用如下的方式查询,那就得先访问name的二级索引树,从二级索引树上取出主键uid,然后回表,用这个uid去主键索引树上取得对应的数据

select * from student where name = "zhangsan";

select * from student where name = "gaoyang";

select * from student where name = "linfeng";

...

The hash index is always built based on an existing B-tree index on the table. InnoDB can build a hash index on a prefix of any length if the key defined for the B-tree

InnoDB存储引擎会做如下优化:如果检测到某个二级索引不断被使用,二级索引成为热数据,那么InnoDB会根据在二级索引树上的索引值在构建一个哈希索引来加速搜索(只适用于等值比较)

MySQL-hash索引_二级索引_02

图中蓝色的箭头表示不建立哈希索引,搜索二级索引树然后回表的过程

黄色箭头就是直接等值比较搜索哈希表,直接拿到数据地址的过程。使用哈希索引O ( 1 ) O(1)O(1)的时间复杂度就访问到哈希索引name,然后取出data即可(对于InnoDB来说应该是直接取得数据,而不是拿到数据地址后再访问)

注意:hash索引的生成和维护也是耗费性能的,并不能绝对的在任何场景下提高对二级索引的搜索效率,我们可以查看相关参数指标,如果自适应哈希索引可以提高效率,那我们使用它,否则我们就关闭它。

自适应哈希索引创建后,就会在等值查询的时候直接查询哈希索引,哈希索引上有数据的地址,这样就省下了辅助索引跟主键索引的搜索时间

其实创建哈希索引也是比较消耗资源的,这里有些衡量参数,要根据衡量参数决定是否打开或者关闭自适应哈希索引,mysql官方文档里面也讲了这个,上面不讲人话部分就是对何时创建自适应哈希索引以及如何禁用哈希索引、哈希索引锁的说明。

查看自适应哈希索引是否开启的命令

show variables like 'innodb_adaptive_hash_index';

查看自适应哈希分区(或者说桶)

show variables like 'innodb_adaptive_hash_index_parts';

两个比较重要的信息要注意,查看命令如下

show engine innodb status\G

能看到RW-latch等待的线程数量,自适应哈希索引默认分配了8个分区,同一个分区等待的线程数量过多

走自适应哈希索引搜索的频率和二级索引树搜索的频率

标签:index,hash,name,索引,搜索,哈希,MySQL
From: https://blog.51cto.com/u_15867943/6507680

相关文章

  • 云原生之使用Docker部署mysql数据库
    (云原生之使用Docker部署mysql数据库)一、检查系统版本[root@node~]#cat/etc/os-releaseNAME="CentOSLinux"VERSION="7(Core)"ID="centos"ID_LIKE="rhelfedora"VERSION_ID="7"PRETTY_NAME="CentOSLinux7(Core)"A......
  • in用不用索引,啥时候能用啥时候不能用,一文说清
    in/or到底能不能用索引应该是肯定的,但有时生效有时不生效,这个能不能量化计算?这是本文想讨论和解答的问题。in到底用不用索引感觉像一桩悬疑片!古早时期的面经,统一说不走索引,在一些程序员脑海中从此留下不可磨灭的印记。有些从业时间较长的程序员脑子里的第一反应就是不走索引,上......
  • 花了一周时间,总算把mysql的加锁搞清楚了,再也不怕间隙锁和next-key了
    接触mysql都知道在mysql中有很多锁,共享锁(S)、排他锁(X)、间隙锁(gap)、next-key,当然还有意向锁、表锁等。今天不讲别的,专门来看下innodb引擎下的锁是什么样子的。现在有这样一条sql语句,你知道是什么锁吗?updatetsetname='1'whereid=10;可能会说是锁住id=10的行锁吧,没错行锁是一......
  • 10. docker方式下的mysql设置主从复制(一主两从)
    上一篇【centos使用docker方式安装mysql】笔记中,我们在三个虚拟机中使用docker方式新建了三个mysql容器服务,那么我们这篇文章来记录下,如何在这三台机器中设置mysql的主从复制功能。其中111服务器作为主节点,112和113两个服务器作为两个从节点,复制111服务器mysq......
  • 2023-06-17:说一说redis中渐进式rehash?
    2023-06-17:说一说redis中渐进式rehash?答案2023-06-17:在Redis中,如果哈希表的数组一直保持不变,就会增加哈希冲突的可能性,从而降低检索效率。为了解决这个问题,Redis会对数组进行扩容,通常是将数组大小扩大为原来的两倍。然而,这个扩容过程会引起元素在哈希桶中的分散,导致元素的移动。由......
  • windows下mysql使用mysqldump定时备份数据库,删除过期备份
    windows下mysql使用mysqldump定时备份数据库,删除过期备份创建备份脚本:@echooffforfiles/p"d:\mysql_backup"/mbackup_*.sql-d-7/c"cmd/cdel/f@path"set"Ymd=%date:~0,4%%date:~5,2%%date:~8,2%"cdD:\Mysql\mysql-8.0.18\binmysqldump--opt......
  • 09. centos使用docker方式安装mysql
    一、创建宿主机物理路径新建/mydata/mysql/data、log和conf三个文件夹mkdir-p/mnt/mysql/logmkdir-p/mnt/mysql/datamkdir-p/mnt/mysql/config或者mkdir/mnt/mysql/{log,data,config}二、直接执行下面这个命令,即可创建成功mysql服务dockerrun-p3306:3306--na......
  • 2023-06-17:说一说redis中渐进式rehash?
    2023-06-17:说一说redis中渐进式rehash?答案2023-06-17:在Redis中,如果哈希表的数组一直保持不变,就会增加哈希冲突的可能性,从而降低检索效率。为了解决这个问题,Redis会对数组进行扩容,通常是将数组大小扩大为原来的两倍。然而,这个扩容过程会引起元素在哈希桶中的分散,导致元素的移动。......
  • nas docker安装mysql 整理
    前提:群晖nas nas已安装docker一、下载MySQL由于查询注册表失败,所以通过ssh工具xshell连接docker来下载MySQL;xshell下载地址:https://www.xshell.com/zh/free-for-home-school/ (填写相关信息,下载免费版本)nas启用ssh功能: xshell连接nas 1.切换到rootsudo-i ......
  • Java_Base7之接口和抽象类、集合类ArrayList、HashSet、HashMap
    一、接口和抽象类(了解)接口:规则,规范行为。只能有抽象方法,一个类可以同时实现多个接口,必须重写所有抽象方法。 接口与接口是继承,接口与类是实现。接口是对继承的补充。 interfaceimplements定义一个接口publicinterfaceInter{ //默认修饰符publicabstract可以省略 pu......