Binary_Checksum与HashBytes函数

时间:2017-04-03 11:20:22

标签: sql sql-server-2012 database-performance checksum hashbytes

我有一个使用大量二进制校验和函数的复杂查询,当我用两个不同记录的测试数据测试它时它实际上返回了相同的校验和值。请找到我在下面使用的测试数据

SELECT BINARY_CHECKSUM(16   ,'EP30461105',1) AS BinaryCheckSumEx UNION ALL
SELECT BINARY_CHECKSUM(21   ,'EP30461155',1) AS BinaryCheckSumEx

现在我正在尝试将HASHBYTES功能用于' MD5'我可以确定获得唯一记录的算法,但我现在关心的是,在当前查询中我使用了'校验和'加入我的合并'用于查找新记录的语句。因为' HashBytes'返回Varbinary数据类型当我用' HashByte'替换连接条件时,我可以期待多少性能开销。领域。

SELECT HASHBYTES('MD5', CONCAT(Col1,Col2,Col3,Col4,..))

而且我需要为多个列创建散列,在这种情况下我需要有一个额外的Concat函数,这会对我的性能产生额外的开销。

1 个答案:

答案 0 :(得分:3)

以下是选项:

  1. 将哈希索引用作VARBINARY

  2. 使用BINARY_CHECKSUM

    • 这很好,但问题是校验和重复的可能性很高,而且谷歌你会看到很多人都有问题。
  3.   

    但是,校验和不会改变的可能性很小。   因此,我们不建议使用CHECKSUM来检测是否   除非您的应用程序偶尔可以容忍,否则值已更改   错过了一个变化。请考虑使用HashBytes。当一个MD5哈希   指定算法,HashBytes返回的概率   两个不同输入的相同结果远低于   CHECKSUM。

    来源:https://msdn.microsoft.com/en-us/library/ms189788(v=SQL.100).aspx

    1. 将HASBYTES转换为BIGINT并在其上具有索引
      • 这不是一个好主意
    2.   

      我还要小心将哈希值转换为BIGINT   鉴于BIGINT只有8个字节,但所有哈希算法 - 甚至是MD5    - 大于8个字节(MD5 = 16个字节,SHA1 = 20,SHA2_256 = 32,SHA2_512 = 64)。并转换大于8字节的二进制值   到BIGINTsilently截断值。因此你会失去准确性   越来越多的误报。以下查询显示   这个行为:

      SELECT CONVERT(BIGINT, 0xFFFFFFFFFFFFFF),      --  7 bytes = 72057594037927935
             CONVERT(BIGINT, 0xFFFFFFFFFFFFFFFF),    --  8 bytes = -1
             CONVERT(BIGINT, 0xFFFFFFFFFFFFFFFFFF),  --  9 bytes = -1
             CONVERT(BIGINT, 0xFFFFFFFFFFFFFFFFFFFF) -- 10 bytes = -1
      

      来源:https://dba.stackexchange.com/questions/154945/index-maintenance-for-varbinary

      1. 将HASHBYTES转换为VARCHAR并具有索引
        • 这是一个不错的选择
        • 您有两种选择:
      2. a)如果您正在使用SQL 2008或更高版本

        SELECT CONVERT(NVARCHAR(32),HashBytes('MD5', CONTENT),2)
        

        b)如果您正在使用SQL 2005

        SELECT SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('MD5', CONTENT)), 3, 32)
        

        PS:如果你想知道应该使用哪种哈希算法:

        MD5 = 16 bytes
        SHA1 = 20 bytes
        SHA2_256 = 32 bytes
        SHA2_512 = 64 bytes
        

        enter image description here

        来源:https://blogs.msdn.microsoft.com/sqlsecurity/2011/08/26/data-hashing-in-sql-server/

        对于第二个问题,您应该将Hash列设为PERSISTED,以避免对运行每个查询产生影响。