SQL Server2014 哈希索引原理

SQL Server2014 哈希索引原理

翻译自http://www.sqlservercentral.com/blogs/sql-and-sql-only/2015/09/08/hekaton-part-6-hash-indexes-intro/

 


在数据库优化中,哈希算法的应用非常广泛,这些哈希操作本质上都是在匹配相同的记录。

尤其是在 哈希 Join 哈希聚合 中。理解 哈希索引 的原理,不仅有助于掌握哈希索引本身的应用,也能帮助你更好地理解哈希 Join哈希聚合的工作原理。



哈希索引背景
SQL Server 2014 引入了一种新的索引类型,称为 哈希索引(Hash Index)。哈希索引是随著SQL Server 2014 版本推出的内存优化表而推出的,是专门在内存优化表上的一种索引。

在理解哈希索引之前,我们首先要了解什么是 哈希函数,这将帮助我们更好地掌握哈希索引的底层机制。

当一个键值对(key-value pair)传递给哈希函数时,哈希函数根据该键值对的 key 生成一个哈希值,并将这个键值对分配到适当的 哈希桶(Hash Bucket)中。



举个例子
假设我们使用一个简单的哈希函数:对 10 取模(% 10)。当 key 为 1525 时,传递到哈希函数后,1525 将存放在第五个哈希桶中,因为 1525 % 10 = 5。同样,537 会存放在第七个哈希桶,2982 会存放在第二个哈希桶,依此类推。
哈希索引的工作机制
在 哈希索引 中,索引列会被传递给哈希函数,生成对应的哈希值,并存储在相应的哈希桶中。每个哈希桶不仅存储索引,还包含指向实际数据行的指针(row pointer)。SQL Server 在需要时通过这些指针定位到具体的数据行,从而提高查找效率。这种机制类似于 Java 中 HashMap 的操作方式。


哈希索引的查询过程
当 SQL Server 使用哈希索引来查找数据或处理 WHERE 子句时,它会经历以下步骤:
1、根据查询条件生成适当的哈希函数
2、索引列通过哈希函数匹配,匹配到对应的哈希桶hash bucket,找到对应哈希桶hash bucket意味着也找到了对应的数据行指针(row pointer)
3、通过数据行指针直接读取所需的数据行。
与传统的 B 树索引 相比,哈希索引具有更简单的结构。它不需要像 B 树索引那样进行层层遍历,因此在某些特定场景下,访问速度显著加快。但是哈希索引的缺点是只有在等值查询时候才能使用。




哈希索引语法示例
以下是创建哈希索引的 SQL 语法示例:

CREATE TABLE dbo.HK_tbl
    (
      [ID] INT IDENTITY(1, 1)
               NOT NULL
               PRIMARY KEY NONCLUSTERED HASH WITH ( BUCKET_COUNT = 100000 ) ,
      [Data] char(32) COLLATE Latin1_General_100_BIN2
                      NULL ,
      [dt] datetime NOT NULL,
    )
    WITH (
         MEMORY_OPTIMIZED =
         ON,
         DURABILITY =
         SCHEMA_AND_DATA);
在 SQL Server 2014 中,内存优化表一旦创建,无法再添加哈希索引。而在 SQL Server 2016 之后,你可以在表创建后添加哈希索引,但这属于离线操作,需要停机进行。

 

 
哈希索引中的 Bucket 数量
BUCKET_COUNT = 100000 定义了哈希索引可以使用的哈希桶的数量。哈希桶的数量是用户在创建哈希索引时指定的,而不是由 SQL Server 动态决定的。值得注意的是,哈希桶的数量总是以 2 的次方值进行四舍五入(例如 1024, 2048, 4096 等)。
重要提示: 适当设置 BUCKET_COUNT 非常重要。如果哈希桶数量过少,哈希冲突会增加,反而会影响性能。因此,合适的哈希桶数量是关键。

 

 


SQL Server 与 MySQL 哈希索引的对比
SQL Server 2014 的哈希索引与 MySQL 的 自适应哈希索引 原理相似。两者的共同目标都是通过消除 B 树索引的层层遍历,提升查找速度。哈希索引在处理海量数据查询时,能够极大地优化性能,尤其是在查找数据命中率较高的情况下。

How does a relational database work这篇文章也有描述hash join的原理,大家可以看一下

 

 

http://mysql.taobao.org/monthly/2019/11/02/#jump
一个hash join算法实现需要三个步骤:
选择合适的连接参与表作为内表(build table),构建hash表;
然后使用另外一个表(probe table)的每一条记录去探测第一步已经构建完成的哈希表寻找符合连接条件的记录;
输出匹配后符合需求的记录;
哈希连接根据内存是否能够存放的下hash表决定把哈希表全部放在内存,还是部分放在内存部分放在磁盘

 


总结

哈希索引通过哈希函数将索引列映射到固定数量的哈希桶中,利用简单且高效的查找方式来提升数据访问速度。它适用于需要快速查找特定值的场景,相较于 B 树索引,它的结构更加简单,访问速度更快。适当配置 BUCKET_COUNT 是优化哈希索引性能的关键。


 

相关文章

MySQL Adaptive hash index

java HashMap那点事

How does a relational database work

 

如有不对的地方,欢迎大家拍砖o(∩_∩)o 

posted @ 2015-09-12 00:17  桦仔  阅读(2433)  评论(2编辑  收藏  举报