将 Columnstore 的社会安全号存储为 DECIMAL(10,9)

AAn*_*rus 2 sql-server columnstore

我正在处理一个非常大的数据库(10B + 行),该数据库对 SSN 和 BirthDate 执行匹配以尝试查找重复记录。该表正在使用列存储压缩(SQL SERVER 2016),我想到我可以将 SSN 保存为 DECIMAL(10,9) 以保留前导零,而不是从 CHAR/VARCHAR 中降低性能。我只是想知道是否有人尝试过这个,或者是否有理由不能按预期工作。我知道我可以转换为 INT 并且只是丢失前导零,但这对我来说似乎是一个更好的解决方案。

ISNULL(TRY_CAST('.' + SSN AS DECIMAL(10,9)),0) AS DecimalSSN

我总是可以将它转换回字符串 RIGHT(TRY_CAST(DecimalSSN AS VARCHAR),9) AS SSN

Joe*_*ish 6

我不会使用 DECIMAL 来存储带有行存储或列存储表的 SSN。与 DECIMAL 相比,INT 数据类型具有以下优点:

  • 使用 SQL Server 通常更快
  • 它允许将位图过滤器下推到存储引擎
  • 如果该列不允许 NULL,那么它允许“完美的散列函数”,它不需要连接中的探测残差。

如果您的 SSN 列需要更好的性能,我会使用前导 1 的 INT。这会保留前导零,这似乎是需要的。您应该以相同的格式存储所有 SSN,并且仅在必要时进行转换。例如,如果您需要将 SSN 作为字符串显示给最终用户,则SELECT RIGHT(CAST(1012345678 AS INT), 9)返回"012345678". 否则使用原始值。

我不知道您的查询是什么样的,但假设您在一个表中有 100k 个 SSN,并且您需要检查这些 SSN 中是否有任何一个出现在具有 10 亿行的不同表中。查询可能如下所示:

SELECT *
FROM dbo.SSNS_TO_CHECK_3 c
WHERE NOT EXISTS (
    SELECT 1
    FROM dbo.ALL_SSNS_CCI_INT_LEADING_1 t
    WHERE c.SSN = t.SSN
)
OPTION (MAXDOP 1);
Run Code Online (Sandbox Code Playgroud)

使用带有前导 1 的 INT 列,上述查询在我的机器上需要 7 秒。使用您提出的 DECIMAL(10, 9) 格式,我的机器需要 63 秒的查询时间。几乎所有的时间都花在位图运算符上。

列存储还有一些其他注意事项,但它们在这里无关紧要。与 DECIMAL(10, 9) 相比,INT 在我所知道的各个方面都优越。