私は、SSNとBirthDateでマッチングを実行して重複レコードを検索する非常に大規模なデータベース(10B +行)に取り組んでいます。テーブルは列ストア圧縮(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
で文字列にキャストできます
DECIMALを使用して、行ストアテーブルまたは列ストアテーブルを持つSSNを格納しません。 INTデータ型には、DECIMALに比べて次の利点があります。
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);
先頭に1が付いたINT列を使用すると、上記の query が私のマシンで7秒かかります。 query を提案したDECIMAL(10、9)形式では、マシンで63秒かかります。ほとんどすべての時間がビットマップ演算子に費やされています。
列ストアには追加の考慮事項がありますが、ここでは関係ありません。 INTは、DECIMAL(10、9)と比較して、私が知っているあらゆる点で優れています。