我有一个使用大量二进制校验和函数的复杂查询,当我用两个不同记录的测试数据测试它时它实际上返回了相同的校验和值。请找到我在下面使用的测试数据
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函数,这会对我的性能产生额外的开销。
答案 0 :(得分:3)
以下是选项:
将哈希索引用作VARBINARY
使用BINARY_CHECKSUM
但是,校验和不会改变的可能性很小。 因此,我们不建议使用CHECKSUM来检测是否 除非您的应用程序偶尔可以容忍,否则值已更改 错过了一个变化。请考虑使用HashBytes。当一个MD5哈希 指定算法,HashBytes返回的概率 两个不同输入的相同结果远低于 CHECKSUM。
来源:https://msdn.microsoft.com/en-us/library/ms189788(v=SQL.100).aspx
我还要小心将哈希值转换为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
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
来源:https://blogs.msdn.microsoft.com/sqlsecurity/2011/08/26/data-hashing-in-sql-server/
对于第二个问题,您应该将Hash列设为PERSISTED,以避免对运行每个查询产生影响。