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/

  • 相关阅读:
    简明Python3教程 12.问题解决
    简明Python3教程 11.数据结构
    【SPOJ 694】Distinct Substrings
    【codeforces Manthan, Codefest 17 C】Helga Hufflepuff's Cup
    【CF Manthan, Codefest 17 B】Marvolo Gaunt's Ring
    【CF Manthan, Codefest 17 A】Tom Riddle's Diary
    【SPOJ 220】 PHRASES
    【POJ 3261】Milk Patterns
    【POJ 3294】Life Forms
    【POJ 1226】Substrings
  • 原文地址:https://www.cnblogs.com/woodytu/p/4620151.html
Copyright © 2011-2022 走看看