在Hekaton里,正确选择哈希存储桶数
今天我使用2048的桶数的哈希索引,往Hakaton里插入100万的记录,测试下在哈希桶数里,哈希冲突(Hash Collision)是如何影响Hekaton的工作量——结果非常非常有意思。首先我想介绍下什么是哈希冲突。
你可能知道(非常希望),在SQL Server 2014里,Hakaton表是以哈希索引(Hash Indexes)实现的。维基百科对此有详细介绍,这是哈希索引的应用基础。 哈希函数将索引键映射到哈希索引中对应的 Bucket,哈希函数的结果决定你的行最终放入那个哈希桶。如果多个键值哈希到同个值,SQL Server会在那个哈希桶里插入,在那个哈希桶有多个入口链接在一起。来看下面的图示(来自维基百科):

从图中可以看到,键值“John Smith“和“Sandra Dee”哈希到同个桶——这里是152号桶。这意味着那2行都存在同个哈希桶里,这会影响INSERT性能,还有SELECT的查询性能。在INSERT期间,SQL Server需要维护链接列表,在SELECT查询期间,SQL Server需要扫描链接列表。
介绍完哈希冲突后,我们来用一个简单的例子演示下哈希冲突对性能的影响。我们来创建带Hekaton表的数据库:
-- Create new database
CREATE DATABASE HashCollisions
GO --Add MEMORY_OPTIMIZED_DATA filegroup to the database.
ALTER DATABASE HashCollisions
ADD FILEGROUP HekatonFileGroup CONTAINS MEMORY_OPTIMIZED_DATA
GO USE HashCollisions
GO -- Add a new file to the previous created file group
ALTER DATABASE HashCollisions ADD FILE
(
NAME = N'HekatonContainer',
FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\HashCollisionsContainer'
)
TO FILEGROUP [HekatonFileGroup]
GO -- Create a simple table
CREATE TABLE TestTable
(
Col1 INT NOT NULL PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 1024),
Col2 INT NOT NULL,
Col3 INT NOT NULL
)
WITH
(
MEMORY_OPTIMIZED = ON,
DURABILITY = SCHEMA_ONLY
)
GO
从代码里可以看到,这里我用的1024的哈希桶数——桶数并不多,然后我会往表里插入1000000的记录。接下来我会创建本机编译的存储过程,这样的话我可以用Hekaton的贼快速度:
-- Create a native compiled Stored Procedure
CREATE PROCEDURE InsertTestData
WITH
NATIVE_COMPILATION,
SCHEMABINDING,
EXECUTE AS OWNER
AS
BEGIN
ATOMIC WITH
(
TRANSACTION
ISOLATION LEVEL = SNAPSHOT,
LANGUAGE = N'us_english'
) DECLARE @i INT = 0 WHILE @i < 1000000
BEGIN
INSERT INTO dbo.TestTable (Col1, Col2, Col3) VALUES (@i,@i, @i) SET @i += 1
END
END
GO
可以看到,这里我用简单的循环来插入1000000条记录。在4核CPU,4G内存的虚拟机上,我们打开时间统计,来执行这个存储过程:
SET STATISTICS TIME ON EXEC dbo.InsertTestData

执行时间差不多有42秒,这已经很慢了。我们不断翻倍桶数到1048576,你会看到随着桶数的增加,性能也得到了不断的提升。
DROP PROCEDURE dbo.InsertTestData
DROP TABLE dbo.TestTable -- Create a simple table
CREATE TABLE TestTable
(
Col1 INT NOT NULL PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 1048576),
Col2 INT NOT NULL,
Col3 INT NOT NULL
)
WITH
(
MEMORY_OPTIMIZED = ON,
DURABILITY = SCHEMA_ONLY
)
GO -- Create a native compiled Stored Procedure
CREATE PROCEDURE InsertTestData
WITH
NATIVE_COMPILATION,
SCHEMABINDING,
EXECUTE AS OWNER
AS
BEGIN
ATOMIC WITH
(
TRANSACTION
ISOLATION LEVEL = SNAPSHOT,
LANGUAGE = N'us_english'
) DECLARE @i INT = 0 WHILE @i < 1000000
BEGIN
INSERT INTO dbo.TestTable (Col1, Col2, Col3) VALUES (@i,@i, @i) SET @i += 1
END
END
GO
我们继续执行这个存储过程:
SET STATISTICS TIME ON EXEC dbo.InsertTestData

执行同个存储过程只需要780毫秒,与第一次用1024个桶数的测试运行,这已经是天大的区别。你也可以用DMV sys.dm_db_xtp_hash_index_stats来看下在你的哈希索引里有几桶被使用:
SELECT * FROM sys.dm_db_xtp_hash_index_stats

这个测试告诉我们什么呢?要为Hekaton的哈希索引的存储桶数,要做出正确的选择,因为它们会大大影响SQL Server的性能!最佳桶数应该是在哈希索引里不同值的个数——另外要保留一些可用空间(在不同值个数上稍加),安全起见。你也不能把选择太高的存储桶数,因为相反你就在浪费内存。在SQL Server里的几乎每个设置——都是基于你的工作量的而定,数据库收缩除外哦!
感谢关注!
参考文章:
https://www.sqlpassion.at/archive/2013/11/23/choose-your-hash-bucket-count-very-wisely-in-hekaton/
在Hekaton里,正确选择哈希存储桶数的更多相关文章
- iOS 正确选择图片加载方式
正确选择图片加载方式能够对内存优化起到很大的作用,常见的图片加载方式有下面三种: //方法1 UIImage *imag1 = [UIImage imageNamed:@"image.png ...
- 全网最全的Windows下Anaconda2 / Anaconda3里正确下载安装OpenCV(离线方式和在线方式)(图文详解)
不多说,直接上干货! 说明: Anaconda2-5.0.0-Windows-x86_64.exe安装下来,默认的Python2.7 Anaconda3-4.2.0-Windows-x86_64.ex ...
- 如何正确选择MySQL数据列类型
MySQL数据列类型选择是在我们设计表的时候经常会遇到的问题,下面就教您如何正确选择MySQL数据列类型,供您参考学习. 选择正确的数据列类型能大大提高数据库的性能和使数据库具有高扩展性.在选择MyS ...
- 全网最全的Windows下Anaconda2 / Anaconda3里正确下载安装爬虫框架Scrapy(离线方式和在线方式)(图文详解)
不多说,直接上干货! 参考博客 全网最全的Windows下Anaconda2 / Anaconda3里正确下载安装OpenCV(离线方式和在线方式)(图文详解) 第一步:首先,提示升级下pip 第二步 ...
- 全网最全的Windows下Python2 / Python3里正确下载安装用来向微信好友发送消息的itchat库(图文详解)
不多说,直接上干货! 建议,你用Anaconda2或Anaconda3. 见 全网最全的Windows下Anaconda2 / Anaconda3里正确下载安装用来向微信好友发送消息的itchat库( ...
- 如何在 vue 项目里正确地引用 jquery 和 jquery-ui的插件
copy内容的网址: https://segmentfault.com/a/1190000007020623 使用vue-cli构建的vue项目,webpack的配置文件是分散在很多地方的,而我们需要 ...
- CockroachDB学习笔记——[译]为什么Go语言是CockroachDB的正确选择
原文链接:https://www.cockroachlabs.com/blog/why-go-was-the-right-choice-for-cockroachdb/ 原作者:Jessica Edw ...
- 小小知识点(二十二)显示屏与主机之间连接,出现无信号字样时,应检查是否正确选择集显和独显VGA接口
显示屏与主机之间连接,出现无信号字样时,应检查是否正确选择集显和独显VGA接口 通过VGA接口判断集成显卡和独立显卡.在台式机主机上,VGA接口竖着放置的说明是集成显卡,VGA接口横着放置的说明是独立 ...
- 如何在 vue 项目里正确地引用 jquery
转载 2016年11月13日 使用vue-cli构建的vue项目,webpack的配置文件是分散在很多地方的,而我们需要修改的是build/webpack.base.conf.js,修改两处的代码 / ...
随机推荐
- TestNG官方文档中文版(4)-运行TestNG
4 - 运行TestNG TestNG可以以不同的方式调用: * Command line * ant * Eclipse * IntelliJ's IDEA 1) 命令行 假 ...
- mysql登录时闪退的问题
之前mysql用着好着,可是今天在启动mysql后输入密码出现了闪退,在任务管理器中发现mysql服务没有启动,当手动启动时提示拒绝访问.在网上查找原因发现问题所在. 问题原因:mysql服务没有安装 ...
- FormatJS – 让你的 Web 应用程序国际化
FormatJS 是一个模块化的集合,保护各种 JavaScript 国际化库,例如格式化数字,日期和字符串.它包括一组建立在 JavaScript 的国际内置插件和全行业的国际化标准,再加上一套集成 ...
- Spring(3)—— Junit框架单元测试
Junit主要用于单元测试,即白盒测试.它是一个开源的由JAVA开发的一个用于测试的框架. Junit的几个基本概念:TestCase,TestSuite,TestFixtrue TestCase:代 ...
- mongodb 查询的用法
想要在C#中使用MongoDB,首先得要有个MongoDB支持的C#版的驱动.C#版的驱动貌似有很多种,如官方提供的samus. 实现思路大都类似.这里我们用官方提供的mongo-csharp-dri ...
- kali 忘记登录密码后重置的方法
首先启动你的卡里系统,等出现引导界面时选择恢复模式.如下图: 再出来一个界面时,选择第二个并按E键进入编辑模式.如下图: 进入编辑模式后找到如下图的代码: 把ro改为rw,并且在.gz 后面写上ini ...
- 图文详细解说DevExpress 2015新版亮点【附文档下载】
历时两个月,翻译自官网的更新说明文档,最后整理成册,文末附PDF地址. DevExpress 在今年6月份发布了正式的2015版本,2015在旧版基础上有明显的升级改进,尤其是DevExtreme.W ...
- 愚人节大狂欢 – ADN DevBlog谎话连篇友谊赛
愚人节过去了,你被捉弄了没有? :) 借这个机会,ADN的哥们儿也发泄狂欢了一把,我们4月1号当天在ADN DevBlog上发了一堆谎话连篇的blog,没有一个说实话的,哈哈.这是我们team内部进行 ...
- ios xcode Code signing failed 解决方案
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "Helvetica Neue"; color: #454545; min ...
- iOS之 APNs全新的APNs苹果15年WWDC大会上的干货
记得14年在dl某大学校招上现场面试iOS时候被问到了APNs也就是苹果的推送问题,当时我表示一脸懵逼,因为当时还没有真正接触做过项目也就了解了个大概,总之当时回答的一塌糊涂!后来回去就在网上仔细查了 ...