人员表(姓名,dob,ssn等)
NewRecords 表(name,dob,ssn)
我想编写一个查询,确定哪个 NewRecords 不以任何方式匹配任何 People (这是一个在 NewRecords中设置标志的更新查询< / em>表)。
具体来说,我想找到 NewRecords ,对于 People 中的所有记录,名字,姓氏和ssn之间的Levenshtein距离大于2。 (即,该人的第一个,最后一个和ssn与人中的那些不同,因此可能不匹配)。
我添加了一个用户定义的Levensthein函数Levenshtein distance in T-SQL,并且已经添加了一个优化,为最大允许距离添加了额外的参数。 (如果计算出的levenstein爬升到允许的最大值以上,则函数会提前退出)。但是查询仍然花费了不可接受的长时间,因为表格很大。
我可以做些什么来加快速度?我如何开始考虑优化和性能?在什么时候我需要开始深入研究sql server的内部结构?
update NewRecords
set notmatchflag=true
from
newRecords elr
inner join People pro
on
dbo.Levenshtein_withThreshold(elr.last,pro.last,2)>2 and
dbo.Levenshtein_withThreshold(elr.first,pro.first,2)>2 and
elr.ssn is null and
elr.dob<>pro.dob
答案 0 :(得分:3)
由于不完全知道表结构和数据类型,我不能100%确定这会起作用,但无论如何都要试一试!
我会在测试时首先检查SQL执行计划,通常会有一些部分占用大部分时间。从那里你应该能够衡量任何索引在何处/是否有用。
我的直觉是你的功能被事物的外观称为A LOT,但希望执行计划将决定是否是这种情况。如果是,则可能是CLR存储过程。
答案 1 :(得分:1)
您的查询似乎没有任何问题(可能除了事实,您希望找到不同值的所有可能组合,在大多数情况下会产生很多结果:)。
无论如何,问题是你的Levenstein函数 - 我假设它们是用T-SQL编写的。即使你对它们进行了优化,它们仍然很弱。你真的应该把它们编译成CLR(你发布的链接已经包含了一个例子) - 这将快一个数量级。
我试图用你所得到的另一个想法是以某种方式减少Levenstein比较的数量。也许找到其他条件,或者反转查询:查找所有MATCHING记录,然后选择剩下的内容(它可以使您引入这些附加条件。
但Levenstein编译为CLR是你最好的选择。
答案 2 :(得分:1)
对于一个跳过值为true的值,如果再次运行它,则不会处理它们 这个距离很贵 - 尽量消除那些没有机会的距离 如果长度相差超过2,那么我认为你不能有距离&lt; = 2.
update NewRecords
set notmatchflag=true
from newRecords elr
inner join People pro
on notmatchflag = false
and elr.ssn is null
and elr.dob <> ro.dob
and dbo.Levenshtein_withThreshold( elr.last, pro.last,2) > 2
and dbo.Levenshtein_withThreshold(elr.first,pro.first,2) > 2