Architecture 从不同(大)数据源查找相似记录的最快方法是什么

Architecture 从不同(大)数据源查找相似记录的最快方法是什么,architecture,algorithm,Architecture,Algorithm,我在一家公共卫生机构工作,那里有很多不同的人口统计数据集——存储在SQL Server、Access和Excel中。我已经编写了一个应用程序,允许人们根据不同的标准在这些数据集中查找“匹配项”,并使用GUI进行设置。例如,一个“匹配”可能是两个数据集中的第一个、最后一个和DOB匹配——但SSN“关闭1”(由Levenshtein算法确定) 这些都是大数据集。匹配条件可能会变得非常复杂。现在,我通过将两个数据集拉入内存中的数据表,然后逐行遍历第一个表,并查看第二个表中是否有匹配的行(使用LINQ)

我在一家公共卫生机构工作,那里有很多不同的人口统计数据集——存储在SQL Server、Access和Excel中。我已经编写了一个应用程序,允许人们根据不同的标准在这些数据集中查找“匹配项”,并使用GUI进行设置。例如,一个“匹配”可能是两个数据集中的第一个、最后一个和DOB匹配——但SSN“关闭1”(由Levenshtein算法确定)

这些都是大数据集。匹配条件可能会变得非常复杂。现在,我通过将两个数据集拉入内存中的数据表,然后逐行遍历第一个表,并查看第二个表中是否有匹配的行(使用LINQ)来查找匹配项。所以我的代码看起来像:

For each table1Row in TableOne/DatasourceOne
    table2Options=from l in table2rows where Levenshtein(table1Row.first, l.first)<2 //first name off by one            
    table2Options=from l in table2rows where Levenshtein(table1Row.last, l.last)<2 //last name off by one 
    if table2Options.count>1 then the row in table1 'matches' table 2      
Next 
对于TableOne/DatasourceOne中的每个table1Row

table2Options=来自table2rows中的l,其中Levenshtein(table1Row.first,l.first)您能否将需要分析的所有数据存入内存,然后进行分析?我替换了如下代码:

for each day in months:
     for each customer in customers:
          computed = computeSalesInDatabase(customer,day)
          saveComputed(computed)
for each day in months:
     dailyData = getFullDay(day)
     for each customer in customers:
          computed = computeSalesInMemory(customer,day,dailyData)
          saveComputed(computed)
代码如下:

for each day in months:
     for each customer in customers:
          computed = computeSalesInDatabase(customer,day)
          saveComputed(computed)
for each day in months:
     dailyData = getFullDay(day)
     for each customer in customers:
          computed = computeSalesInMemory(customer,day,dailyData)
          saveComputed(computed)

并且发现它的性能更好

如果
LastName
不匹配,则添加and If语句以不检查
FirstName

99%的
LastName
s不匹配。。因此,您很少会对名字进行检查。这将使您的处理时间减少近一半



您可以做的另一件事是添加更多规则(当然,您必须这样做,同时保持浓密的意图完好无损)。。例如:如果您添加一条规则说“姓氏的第一个字母必须匹配”,那么您可以先根据这个规则进行过滤,从而大大提高效率

我将考虑将其转向某种非SQL类型的实现。您可能想查看上的这篇StackOverflow文章以了解更多信息

如果您不能使用完整的NoSQL实现,那么您可能需要从中吸取一些想法,例如使用键值对来形成数据之间的连接

on Levenshtein引用了一些可能的改进,这些改进应该会有所帮助。在您的情况下,因为您只对阈值以下的距离感兴趣,所以应该注意,如果字符串大小相等(例如在社会保险号码中),则可以使用汉明距离。对于大小不等的字符串,只需计算矩阵中2k+1的对角线条纹,其中k是阈值


相对运行两个字符串列表应该能够在Levenshtein算法中提供一些优化。例如,比较以“a”开头的单词的替换将适用于以“a”开头的所有单词。我会看看是否能想出一个已经以这种方式进行优化的参考算法。

是否可以缓存
table1Row.first,l.first
table1Row.last,l.last
的前n个组合及其相关数据,因此对于这些情况,您只需搜索缓存数据,而不必搜索整个表?您可能需要做一些使用情况分析,看看这在您的案例中是否有意义。整合您的数据。或者每晚运行一个作业来计算可能的匹配,并将这些结果存储在您的一个数据源中,然后查找,而不是动态计算。RBAR(一行接一行)操作的速度是出了名的慢。谢谢大家——但不幸的是缓存解决方案不起作用。关键是允许在意外数据源之间进行匹配。我正在寻找一种绕过RBAR的方法,但不确定是否有解决方法,因为我需要为每个可能的组合计算levenshtein函数。这个问题可能更适合,并且得到更好的答案。@JonRaynor-同意,他需要将所有数据放在一个数据库中。特别是因为他有未加密/可解密的SSN——引用的位置越少越好。你的意思是缓存计算值/提前计算它们吗?或者在开始时计算所有值,然后使用它们?这两种解决方案都没有多大帮助,因为(1)我不知道会提前要求什么匹配(2)有太多太多的值需要计算来计算它们/将它们全部存储在ram中。在重新阅读您的帖子(您添加了信息吗?)时,我上面的建议似乎没有多大帮助,听起来你已经做了一点。谢谢@笨蛋们。我已经在按你的建议做了。表2中的每个选项都缩小了可能性。第二次调查表2选项时,它已经排除了非第一次点击。哦。。您仍然可以颠倒顺序,先使用LastName:)。这应该会有所帮助……谢谢卡尔。我已经修改了一些Levenshein来优化它。我的实现采用“大于”参数。如果字符串之间的距离大于参数,则输出1000作为距离。此外,对于矩阵中的对角值,如果发现迄今为止计算的levenshtein距离大于参数,它会提前退出并返回1000。只是出于好奇,为什么NoSQL解决方案在这里会更好?@jcolebrand-我一直在想,当涉及到需要快速完成复杂查询要求的大型数据集时,应该有一个可扩展的解决方案。但是,除非你只是在卸载大量计算,否则这不是更快的方法。我向您保证,优化的MS SQL实例或Oracle配置也会同样快。@jcolebrand-这在很大程度上取决于数据的性质和搜索的复杂性。我一直在使用一些医学文档处理测试,它比我以前使用的一些技术做得更好。它可能不会更好,但值得研究,看看它是否适合,或者是否有算法思想可以借鉴。