如何加快这个T-SQL查询

问题描述:

表的人(姓名,出生日期,身份证等)
NewRecords(姓名,出生日期,SSN)
我想写的是确定哪些NewRecords查询不以任何方式匹配任何(这是一个更新查询,在NewRecords表中设置了一个标志)。如何加快这个T-SQL查询

具体来说,我想找到NewRecords为它的第一个名字,姓氏和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

执行计划? – Kermit 2013-04-29 13:49:47

+0

你有没有试过C#CLR存储过程?这些字符串操作比SQL用户定义的函数要好得多。 – Andomar 2013-04-29 13:53:12

+1

Scalar UDF在SQL Server上的性能令人失望。再加上搜索子句中的大部分函数和表达式都会阻止它能够使用该部分搜索的索引。如果您向我们展示您的UDf的代码,我们可能会将其转化为可以更好地优化的东西。 – RBarryYoung 2013-04-29 13:57:45

由于不确切地知道表结构和数据类型,我不是100%确定这可以工作,而是无论如何都要坚持下去!

我会在测试它时首先检查SQL执行计划,通常会有一些部分花费最多的时间。从那里你应该能够衡量哪里/哪些指标会有所帮助。

虽然我的直觉是你的功能被称为很多东西的外观,但希望执行计划将确定是否是这种情况。如果是这样,那么CLR存储过程可能就是要走的路。

你的查询似乎没有什么问题(除了事实上,你想找到所有可能的不同值的组合,在大多数情况下会给出很多结果:))。

无论如何,问题在于你的Levenstein函数 - 我认为它们是用T-SQL编写的。即使你优化了它们,它们仍然很脆弱。你真的应该把它们编译成CLR(你发布的链接已经包含了一个例子) - 这将会快上一个数量级。

另一个想法,我会尝试与你有什么,是以某种方式减少莱文斯坦比较的数量。也许找其他条件,或反向查询:寻找所有匹配的记录,然后选择还剩下些什么(它可以使您介绍这些附加条件

但莱文施泰因编译为CLR是您最好的选择

有关。一个跳过的值是真的,所以如果你再次运行它,那么它将不会处理这些
这个距离是昂贵的 - 尝试消除那些没有机会第一
如果长度相差超过2那么我认为你不会有距离< = 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