Pra*_*azz 5 sql checksum database-performance sql-server-2012 hashbytes
我有一个复杂的查询,它使用大量的二进制校验和函数,当我用两个不同记录的一些测试数据对其进行测试时,实际上返回了相同的校验和值。请在下面找到我使用的测试数据
SELECT BINARY_CHECKSUM(16 ,'EP30461105',1) AS BinaryCheckSumEx UNION ALL
SELECT BINARY_CHECKSUM(21 ,'EP30461155',1) AS BinaryCheckSumEx
Run Code Online (Sandbox Code Playgroud)
现在,我正在尝试将HASHBYTES函数与“ MD5”算法一起使用,可以肯定地为其获取唯一记录,但是现在让我担心的是,在当前查询中,我使用“校验和”值来加入“合并”语句寻找新记录。由于“ HashBytes”返回我Varbinary数据类型,所以当我用“ HashByte”字段替换联接条件时,可以期望多少性能开销。
SELECT HASHBYTES('MD5', CONCAT(Col1,Col2,Col3,Col4,..))
Run Code Online (Sandbox Code Playgroud)
而且,我需要为多个列创建哈希,在这种情况下,我需要具有一个额外的Concat函数,这会对我的性能产生额外的开销。
以下是选项:
在散列上使用索引作为VARBINARY
使用BINARY_CHECKSUM和CHECKSUM
但是,校验和几乎不变的可能性很小。因此,除非您的应用程序可以容忍偶尔丢失更改,否则我们不建议您使用CHECKSUM来检测值是否已更改。考虑改用HashBytes。当指定了MD5哈希算法时,对于两个不同的输入,HashBytes返回相同结果的概率要比CHECKSUM的概率低得多。
来源:https : //msdn.microsoft.com/zh-cn/library/ms189788(v=SQL.100).aspx
考虑到BIGINT只有8个字节,但所有哈希算法-甚至是MD5-都大于8个字节(MD5 = 16个字节,SHA1 = 20,SHA2_256 = 32和SHA2_512),我也将谨慎地将哈希值转换为BIGINT = 64)。将大于8个字节的二进制值转换为BIGINT会静默地截断这些值。因此,您会失去准确性,并会增加误报率。以下查询显示此行为:
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
Run Code Online (Sandbox Code Playgroud)
资料来源:https : //dba.stackexchange.com/questions/154945/index-maintenance-for-varbinary
a)如果您使用的是SQL 2008或更高版本
SELECT CONVERT(NVARCHAR(32),HashBytes('MD5', CONTENT),2)
Run Code Online (Sandbox Code Playgroud)
b)如果您使用的是SQL 2005
SELECT SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('MD5', CONTENT)), 3, 32)
Run Code Online (Sandbox Code Playgroud)
PS:如果您想知道应该使用哪种哈希算法:
MD5 = 16 bytes
SHA1 = 20 bytes
SHA2_256 = 32 bytes
SHA2_512 = 64 bytes
Run Code Online (Sandbox Code Playgroud)
来源:https://blogs.msdn.microsoft.com/sqlsecurity/2011/08/26/data-hashing-in-sql-server/
对于第二个问题,应将Hash列设为PERSISTED,以避免对运行每个查询产生影响。
| 归档时间: |
|
| 查看次数: |
4359 次 |
| 最近记录: |