评估TSQL BINARY_CHECKSUM()单/拆分用法的漏检概率差异
问题背景
现有一张40万行、13列的表,列包含日期、GUID、varchar、text等多种数据类型,其中5列为低基数列,8列为高基数列。使用BINARY_CHECKSUM()检测行变更,需对比两种用法的漏检概率:
- 单个
BINARY_CHECKSUM()包含全部13列 - 将列拆分到两个
BINARY_CHECKSUM()中
已知两种用法的额外处理开销可忽略(子树成本18.7 vs 17.5),无需实现100%变更检测,可接受“小”漏检率,核心疑问是:在几乎无额外CPU开销的情况下,拆分计算能否将漏检率从“小”降至“极小”,还是差异可忽略?
核心分析
BINARY_CHECKSUM()的漏检本质是哈希碰撞:当行数据发生变更,但计算出的校验值与原校验值相同时,就会出现漏检。- 单个校验的碰撞概率:假设单个
BINARY_CHECKSUM()的碰撞概率为P,漏检概率即为P。由于BINARY_CHECKSUM()输出是32位整数,理论上单个碰撞概率约为1/(2^32)。 - 拆分双校验的碰撞概率:只有当两个
BINARY_CHECKSUM()同时发生碰撞时,才会漏检。假设两个校验的碰撞概率分别为P1和P2,联合漏检概率为P1*P2,约为1/(2^64),这个概率已经极小,几乎可以忽略不计。 - 结合你的表结构:拆分时将列分成两组(示例中为6列和7列),不会改变单校验的碰撞概率,但双校验同时碰撞的可能性会呈数量级下降,确实能把漏检率从“小”降到“极小”,且开销几乎无差异,这种优化是值得的。
代码示例
DECLARE @now as datetime2(0) = sysdatetime(); IF OBJECT_ID('tempdb..#my_bin_ckecksum') IS NOT NULL DROP TABLE #my_bin_ckecksum; SELECT tbl.ID ,BINARY_CHECKSUM(GUID1, GUID2, Date1, Date2, varchar1, Date3, varchar2, varchar3, varchar4, GUID3, Date4, Text1, varchar5) as BinaryChecksum ,@now as Checkdate INTO #my_bin_ckecksum FROM dbo.my_table tbl; IF OBJECT_ID('tempdb..#my_bin_ckecksum2') IS NOT NULL DROP TABLE #my_bin_ckecksum2; SELECT tbl.ID -- 拆分双校验是否能降低实际变更却未被检测到的概率 ,BINARY_CHECKSUM(GUID1, GUID2, Date1, Date2, varchar1, Date3) as BinaryChecksum1 ,BINARY_CHECKSUM(varchar2, varchar3, varchar4, GUID3, Date4, Text1, varchar5) as BinaryChecksum2 ,@now as Checkdate INTO #my_bin_ckecksum2 FROM dbo.my_table tbl;
内容的提问来源于stack exchange,提问作者DatumPoint
相关产品推荐
相关产品推荐

