我有一个名为tblClient
的表,其中包含一个名为SSN
的加密列。
由于公司政策,我们使用对称密钥(由于性能原因选择非对称密钥)使用密码加密SSN
。
以下是对LIKE
的部分SSN
搜索
声明@SSN varchar(11)
设置@SSN ='111-22 - %'
open symmetric key SSN_KEY decrypt by password = 'secret'
select Client_ID
from tblClient (nolock)
where convert(nvarchar(11), DECRYPTBYKEY(SSN)) like @SSN
close symmetric key SSN_KEY
在加密之前,搜索150,000条记录的时间少于 1 秒 但是在解密的情况下,相同的搜索需要 5 秒。
我可以采用哪种策略来尝试通过加密列优化搜索?
答案 0 :(得分:3)
一个难以克服的问题是使用通配符搜索需要某种索引或表扫描,这需要对每一行进行解密。
通过预先加密搜索值来优化,以允许对加密值进行索引。
如果您要求显式匹配,您可以执行类似的操作,请注意加密是对输入值而不是列进行的:
select Client_ID
from tblClient (nolock)
where SSN = convert(nvarchar(11), ENCRYPTBYKEY(@SSN))
然而......对于搜索,您可能希望通过将SSN的片段放入单独的索引字段,然后解析输入字符串来查看实现此目的的优化。做
select Client_ID
from tblClient (nolock)
where SSNFIRST3 = convert(nvarchar(3), ENCRYPTBYKEY( <parsed prefix here> ))
and SSNSECOND2 = convert(nvarchar(2), ENCRYPTBYKEY( <parsed middle section here> ))
您只对输入值进行加密/解密,而不是行。
假设您编写了一些简单的正则表达式代码,将搜索字符串解析为单独的部分以提供上述查询。上述情况的影响至少可以使用索引搜索,因为访问的行数有限,索引搜索速度应该比现在快得多。
编辑:我的意思是ENCRYPTBYKEY,改为上面。答案 1 :(得分:3)
简单的解决方案是为SSN的第一个字符添加未加密的列。并this is the hard one。
答案 2 :(得分:1)
我的猜测是,通过加密列,每次查询时都会强制进行全表扫描(尽管检查计划是否确定)。通过SSN创建索引会使加密变得毫无意义。