【发布时间】:2017-12-20 16:45:52
【问题描述】:
我有一个 Microsoft SQL Server 数据库表,其中包含大约 700 万条众包记录,主要包含带有一些相关细节的字符串名称值。对于几乎每条记录,似乎都有十几个类似的拼写错误记录,我正在尝试进行一些模糊匹配来识别记录组,例如“Apple”、“Aple”、“Apples”、“Spple”等。这些名称也可以包含多个单词,它们之间有空格。
我想出了一个使用编辑距离标量函数的解决方案,该函数返回从 string1 转换为 string2 所需的击键次数,并使用该函数将表连接到自身。正如您可以想象的那样,它的性能并不好,因为它必须执行数百万次函数来评估连接。
所以我把它放在一个游标中,因此一次至少只评估一个 string1,这至少会得到结果,但在让它运行几周后,它只评估了 150,000 条记录。有 700 万要评估,我认为我没有我的方法需要的那种时间。
我在字符串名称上放置了全文索引,但是当我没有要搜索的静态值时,我真的找不到使用全文谓词的方法。
有什么想法可以让我以不需要几个月的时间来执行以下操作吗?
SELECT t1.name, t2.name
FROM names AS t1
INNER JOIN names AS t2
ON EditDistance(t1.name,t2.name) = 1
AND t1.id != t2.id
【问题讨论】:
-
这个问题让我想起了soundex函数。
-
好吧,您的查询的问题在于它几乎就像一个笛卡尔连接。 700 万交叉加入 700 万。并且无法使用索引。哎哟。也许您应该创建一个包含所有已知字典单词的表。并使用该字典仅从您的表中选择未知单词。
-
是的,笛卡尔连接绝对是问题所在。字典方法似乎很有趣,但另一个问题是名称是多种语言的,并且可以从字面上包含这些语言中的任何单词或单词组合。我不确定我能否获得一个确定的来源用作字典。
-
好吧,也许您可以在表中添加一列,其中包含单词的 4 个字符的 soundex 值。然后在该字段上放置一个索引。然后通过也加入该字段,它至少会最小化加入的记录数量。虽然你可能不会得到每一个模糊匹配,但它应该运行得更快。
标签: sql sql-server full-text-search fuzzy-search data-cleaning