MySQL:索引与算法(自适应哈希索引)

asds哈希算法是一种常见算法,时间复杂度为O(1), 且不只存在于索引中,每个数据库应用中都存在该数据库结构。设想一个问题,当前服务器的内存为128GB 时,用户怎么从内存中得到某一个被缓存的页呢? 虽然内存中查询速度很快,但是也不可能每次都要遍历所有内存来进行查找,这时对于字典操作只需O(1) 的哈希算法就有了很好的用武之地。

asdsadasdasdasdsadasdasdasdsadassdasdsadasdasdsadasdsadassadasdas————《MySQL技术内幕INNODB存储引擎》


哈希算法

哈希表

ssdss 哈希表(Hash Table) 也称散列表,由 直接寻址表 改进而来。

aassa直接寻址表:用一个数组(即直接寻址表) T [O … m-1] 表示动态集合,其中每个位置(或称槽或桶)对应全域U 中的一个关键字。槽K 指向集合中一个关键字为K 的元素。如果该集合中没有关键字为K 的元素,则T [k] =NULL 。

sdssa直接寻址技术存在一个很明显的问题:

ssdsssa如果域U 很大,在一台典型计算机的可用容量的限制下,要在机器中存储大小为U 的一张表T 就有点不实际,甚至是不可能的。如果实际要存储的关键字集合K 相对于U 来说很小,那么分配给T 的大部分空间都要浪费掉。
在这里插入图片描述
ssdsssa改进:哈希表出现了。在哈希方式下,该元素处于 h(k) 中,即利用哈希函数h,根据关键字k 计算出槽的位置。函数h 将关键字域U 映射到哈希表T [O … m-1] 的槽位。哈希表技术很好地解决了直接寻址遇到的问题,但是这样做有一个小问题,如两个关键字可能映射到同一个槽上。一般将这种情况称之为发生了碰撞(collision) 。在数据库中一般采用最简单的碰撞解决技术,这种技术被称为链接法在这里插入图片描述
ssdsssa哈希函数:必须可以很好地进行散列,一般采用除法散列的方法。h(k) = k mod m

lnnoDB 存储引擎中的哈希算法

ssdss InnoDB 存储引擎使用哈希算法来对字典进行查找,其冲突机制采用链表方式,哈希函数采用除法散列方式。对于缓冲池页的哈希表来说,在缓冲池中的Page 页都有一个chain 指针,它指向相同哈希函数值的页(相当于碰撞后的链表)。

aassa对于缓冲池页的哈希表来说,在缓冲池中的Page 页都有一个 chain 指针,它指向相同哈希函数值的页。而对于除法散列, m 的取值为略大于2 倍的缓冲池页数最的质数。

aassaeg:当前参数innodb_ buffer_pool_ size 的大小为 l0M, 则共有640 个16KB 的页。对于缓冲池页内存的哈希表来说,需要分配640X2=1280 (因640*16=10240)个槽,但是由于1280 不是质数,需要取比1280 略大的一个质数,应该是1399, 所以在启动时会分配1399 个槽的哈希表,用来哈希查询所在缓冲池中的页。

aassaInnoDB 存储引擎的缓冲池对于其中的页是怎么进行查找的呢?上面只是给出了一般的算法,怎么将要查找的页转换成自然数呢?
aassa答:InnoDB 存储引擎的表空间都有一个space_id, 用户所要查询的应该是某个表空间的某个连续16KB 的页,即偏移量offset 。InnoDB 存储引擎将space_id 左移20 位,然后加上这个space_id 和offset,然后通过除法散列到各个槽中去。

自适应哈希索引

ssdss 自适应哈希索引采用之前讨论的哈希表的方式实现。不同的是,这仅是数据库自身创建并使用的, DBA 本身并不能对其进行干预。自适应哈希索引经哈希函数映射到一个哈希表中,因此对于字典类型的查找非常快速.

aassa注:哈希索引只能用来搜索等值的查询,而对于其他查找类型,如范围查找,是不能使用哈希索引的。可以通过参数innodb_adaptive_hash_ index 来禁用或启动此特性,默认为开启。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值