浅谈 Go 语言高性能哈希表的设计与实现

本文深入探讨了Go语言如何实现高性能哈希表,对比了链地址法和开放寻址法,介绍了MatrixOne数据库中哈希表的设计与优化,包括哈希函数、探测方法等,通过性能测试验证了优化效果,特别是在高基数情况下优于其他实现。
摘要由CSDN通过智能技术生成

目录

1. MatrixOne数据库是什么?

2. 哈希表数据结构基础

3. 哈希表基本设计与对性能的影响

    3.1 链地址法

    3.2 开放寻址法

    3.3 碰撞处理

    3.4 Max load factor

    3.5 Growth factor

    3.6 空闲桶探测方法

4. 一些常见的哈希表实现

    4.1C++ 

    4.2std::unordered_map/boost::unordered_map

    4.3 go map

    4.4 swisstable

    4.5 ClickHouse的哈希表实现

5. 高效哈希表的设计与实现

    5.1 基本设计与参数选择

    5.2 哈希函数

    5.3 特殊优化

    5.4 具体实现代码

6. 性能测试

    6.1 测试环境

    6.2 测试内容

    6.3 整数key结果

    6.4字符串key结果

7. 总结

1

MatrixOne数据库是什么?

MatrixOne是一个新一代超融合异构数据库,致力于打造单一架构处理TP、AP、流计算等多种负载的极简大数据引擎。MatrixOne由Go语言所开发,并已于2021年10月开源,目前已经release到0.3版本。在MatrixOne已发布的性能报告中,与业界领先的OLAP数据库Clickhouse相比也不落下风。作为一款Go语言实现的数据库,居然可以与C++实现的顶级OLAP数据库性能媲美,这其中就涉及到了很多方面的优化,包括高性能哈希表的实现,本文就将详细说明MatrixOne是如何用Go实现高性能哈希表的。

Github地址:https://github.com/matrixorigin/matrixone

2

哈希表数据结构基础

哈希表(Hashtable)是一种非常基础的数据结构,对于数据库的分组聚合和Join查询的性能至关重要。以如下的分组聚合为例(备注,图引自参考文献1):

SELECT col, count(*) FROM table GROUP BY col

6b12d33bf78eb5162da8c888f57ead3e.png
groupby

它包含两个处理阶段:第1阶段是使用数据源的数据建立一个哈希表。哈希表中的每条记录都与一个计数器有关。如果记录是新插入的,相关的计数器被设置为1;否则,计数器被递增。第二阶段是将哈希表中的记录集合成一种可用于进一步查询处理的格式。

对于Join查询而言,以如下SQL为例:

SELECT A.left_col, B.right_col FROM A JOIN B USING (key_col)

106a5d19242690ccf5fbe084e1c7aee0.png
join

它同样也有两个阶段:第一阶段是使用Join语句右侧表的数据建立一个哈希表,第二阶段是从左侧表中读取数据,并快速探测刚刚建立的哈希表。构建阶段与上面的分组实现类似,但每个哈希表的槽位都存储了对右边列的引用。

由此可见,哈希表对于数据库的SQL基础能力起着很关键的作用 ,本文讨论哈希表的基本设计与对性能的影响,比较各种常见哈希表实现,然后介绍我们为MatrixOne实现的哈希表的设计选择与工程优化,最后是性能测试结果。

我们预设读者已经对文中提到哈希表相关的概念有所了解,主要讨论其对性能的影响,不做详细科普。如果对基本概念并不了解,请从其他来源获取相关知识,例如维基百科。

3

哈希表基本设计与对性能的影响

碰撞处理

不同的key经哈希函数映射到同一个桶,称作哈希碰撞。各种实现中最常见的碰撞处理机制是链地址法(chaining)和开放寻址法(open-address

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值