zoukankan      html  css  js  c++  java
  • 在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表的数据库:

     1 -- Create new database
     2 CREATE DATABASE HashCollisions
     3 GO
     4 
     5 --Add MEMORY_OPTIMIZED_DATA filegroup to the database.
     6 ALTER DATABASE HashCollisions
     7 ADD FILEGROUP HekatonFileGroup CONTAINS MEMORY_OPTIMIZED_DATA
     8 GO
     9 
    10 USE HashCollisions
    11 GO
    12 
    13 -- Add a new file to the previous created file group
    14 ALTER DATABASE HashCollisions ADD FILE
    15 (
    16     NAME = N'HekatonContainer', 
    17     FILENAME = N'C:Program FilesMicrosoft SQL ServerMSSQL12.MSSQLSERVERMSSQLDATAHashCollisionsContainer'
    18 )
    19 TO FILEGROUP [HekatonFileGroup]
    20 GO
    21 
    22 -- Create a simple table
    23 CREATE TABLE TestTable
    24 (
    25     Col1 INT NOT NULL PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 1024),
    26     Col2 INT NOT NULL,
    27     Col3 INT NOT NULL
    28 )
    29 WITH
    30 (
    31     MEMORY_OPTIMIZED = ON, 
    32     DURABILITY = SCHEMA_ONLY
    33 )
    34 GO

    从代码里可以看到,这里我用的1024的哈希桶数——桶数并不多,然后我会往表里插入1000000的记录。接下来我会创建本机编译的存储过程,这样的话我可以用Hekaton的贼快速度: 

     1 -- Create a native compiled Stored Procedure
     2 CREATE PROCEDURE InsertTestData
     3 WITH 
     4     NATIVE_COMPILATION, 
     5     SCHEMABINDING, 
     6     EXECUTE AS OWNER
     7 AS 
     8 BEGIN
     9     ATOMIC WITH 
    10     (
    11         TRANSACTION 
    12         ISOLATION LEVEL = SNAPSHOT,
    13         LANGUAGE = N'us_english'
    14     )
    15 
    16     DECLARE @i INT = 0
    17     
    18     WHILE @i < 1000000
    19     BEGIN
    20         INSERT INTO dbo.TestTable (Col1, Col2, Col3) VALUES (@i,@i, @i)
    21 
    22         SET @i += 1
    23     END
    24 END
    25 GO

    可以看到,这里我用简单的循环来插入1000000条记录。在4核CPU,4G内存的虚拟机上,我们打开时间统计,来执行这个存储过程:

    1 SET STATISTICS TIME ON
    2 
    3 EXEC dbo.InsertTestData

    执行时间差不多有42秒,这已经很慢了。我们不断翻倍桶数到1048576,你会看到随着桶数的增加,性能也得到了不断的提升。

     1 DROP PROCEDURE dbo.InsertTestData
     2 DROP TABLE dbo.TestTable
     3 
     4 -- Create a simple table
     5 CREATE TABLE TestTable
     6 (
     7     Col1 INT NOT NULL PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 1048576),
     8     Col2 INT NOT NULL,
     9     Col3 INT NOT NULL
    10 )
    11 WITH
    12 (
    13     MEMORY_OPTIMIZED = ON, 
    14     DURABILITY = SCHEMA_ONLY
    15 )
    16 GO
    17 
    18 
    19 -- Create a native compiled Stored Procedure
    20 CREATE PROCEDURE InsertTestData
    21 WITH 
    22     NATIVE_COMPILATION, 
    23     SCHEMABINDING, 
    24     EXECUTE AS OWNER
    25 AS 
    26 BEGIN
    27     ATOMIC WITH 
    28     (
    29         TRANSACTION 
    30         ISOLATION LEVEL = SNAPSHOT,
    31         LANGUAGE = N'us_english'
    32     )
    33 
    34     DECLARE @i INT = 0
    35     
    36     WHILE @i < 1000000
    37     BEGIN
    38         INSERT INTO dbo.TestTable (Col1, Col2, Col3) VALUES (@i,@i, @i)
    39 
    40         SET @i += 1
    41     END
    42 END
    43 GO

    我们继续执行这个存储过程:

    1 SET STATISTICS TIME ON
    2 
    3 EXEC dbo.InsertTestData

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

    1 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/

  • 相关阅读:
    Python 字符串操作
    Python 字典操作
    16 飞机大战:思路整理、重要代码
    15 飞机大战:pygame入门、python基础串连
    14 windows下安装pygame模块
    13 制作模块压缩包、安装模块
    12 包及导包
    11 模块、模块的搜索顺序、__file__内置属性、__name__属性
    异常集
    10 异常
  • 原文地址:https://www.cnblogs.com/woodytu/p/4620151.html
Copyright © 2011-2022 走看看