在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,修改两处的代码 / ...
随机推荐
- C++学习笔记13:运算符重载(赋值操作符2)
移动语义 完成所有权的移交,当拷贝构造和赋值构造时,目标对象的所有权必须移交给我们的新的对象,原始对象将丧失所有权,_p指针将不再指向原来的那个数组: 左值与右值 C原始定义 左值:可以出现在赋值号的 ...
- mysql定时任务简单例子
mysql定时任务简单例子 ? 1 2 3 4 5 6 7 8 9 如果要每30秒执行以下语句: [sql] update userinfo set endtime = now() WHE ...
- linux常用命令之查阅文件
CAT cat – concatenate print files 连续的输出文件内容 用法 cat [-nbA] file 选项 -n line number 输出行号 -b line number ...
- Webform(Linq高级查、分页、组合查询)
一.linq高级查 1.模糊查(包含) 1 public List<User> Select(string name) 2 { 3 return con.User.Where(r => ...
- Vue-router中文教程-Vue-router参考手册.CHM
下载地址http://download.csdn.net/detail/shouce_ren/9689243 百度云下载地址
- go语言 rune切片
go语言 rune切片 示例 package main import ( "fmt" ) //http://www.cnblogs.com/osfipin/ func main() ...
- iOS 适配iOS9
1.网络接口不支持https协议,在iOS9下 在iOS9下,系统默认会拦截对http协议接口的访问,因此无法获取http协议接口的数据. 解决方案(以下方法2选1): (1)暂时退回到http协议 ...
- OpenGL显示图片
最近想用C++在windows下实现一个基本的图像查看器功能,目前只想到了使用GDI或OpenGL两种方式.由于实在不想用GDI的API了,就用OpenGL的方式实现了一下基本的显示功能. 用GDAL ...
- 《Kotlin for android Developers》中文翻译
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4939080.html 之前一直在关注Kotlin和Androi ...
- Android Contextual Menus之二:contextual action mode
Android Contextual Menus之二:contextual action mode 接上文:Android Contextual Menus之一:floating context me ...