2017-10-09 37 views
0

我正在清理一个我继承的脏数据库,并且需要对模糊匹配名称进行人工审查。我提出了一个可行的解决方案,但速度非常慢 - 15k行7分钟。我有这种感觉,我忽略了一些非常简单的解决方案。MySQL优化查询“模糊匹配”重复?

记录示例:

1 John Smith 
2 John Q Smith 
3 Janway Smith 
4 Jane Chen 
5 David Jones 
6 Natalia La Brody 
7 Natalia LaBrody 
8 LaBrody 
9 Dave Jones 

我需要为这个模糊匹配多个条件。两个我想出了包括:

  1. 检查匹配的前三名和最后五个字母的concat。
  2. 如果对所有的最后一句话一个字检查
  3. (我可以添加更多的条件)

我的代码如下所示:

UPDATE authors a 
INNER JOIN (SELECT id, author_name FROM authors) b 
    ON CASE WHEN a.author_name NOT REGEXP ' ' 
     THEN 
      a.author_name = 
      substring_index(b.author_name, ' ', -1) 
     ELSE 
      concat(LEFT(a.author_name, 3), RIGHT(a.author_name, 5)) = 
      concat(LEFT(b.author_name, 3), RIGHT(b.author_name, 5)) 
     END 
SET tags = concat_ws(',',tags,'Duplicate?') 
WHERE a.id <> b.id 

我很惊讶,我可以把一个CASE一个ON条款,但它的工作。尽管如此,我该如何以更好的表现来做到这一点呢?

回答

0

数据库(一般)不是为此目的而设计的。

使用的一种算法是Levenshtein distance。你可以很容易地找到MySQL的实现,但这并没有帮助你的问题。

说实话,这样的字符串匹配通常需要手动检查。您可能会考虑将数据加载到电子表格中,按字母顺序排序,并在电子表格中记录相同的值。最后,您将不得不花费大量时间来确定“重复”的位置,因此您不妨在此基础上计划工作量。

+0

我后指出人工检验的需求。这是为了加快这一进程,否则我们手动检查15,000条没有优先级的记录。但是感谢Levenshtein距离的提示,这可能会有所帮助。 – Slam

+0

Levenshtein距离计算大量耗时,并且可悲地根本无助于回答原始问题。 – Slam

1

一种方法是使用soundex。你不能100%依赖于它,但它帮助你缩小你的搜索结果,使查询快速

select t, soundex(t) from 
(
select 'John Smith' as t 
union 
select 'John Q Smith' as t 
union 
select 'Janway Smith' as t 
union 
select 'Jane Chen' as t 
union 
select 'David Jones' as t 
union 
select 'Natalia La Brody' as t 
union 
select 'Natalia LaBrody' as t 
union 
select 'LaBrody' as t 
union 
select 'dave jones' as t 
)tbl 
group by soundex(t) 

输出

'Natalia La Brody', 'N34163' 
'LaBrody', 'L163' 
'John Smith', 'J5253' 
'Jane Chen', 'J525' 
'David Jones', 'D13252' 
'dave jones', 'D1252' 
+0

我不知道soundex是一个本地函数!优点:它超快。缺点:我的数据有98%的误报。这是完全错误的。它成功地显示了重复,如果有一个中间首字母,但是绝大多数是这样的:'K325:KJ Dakin,Keith Gessen,Kate Zezima,Katie Kane,Kathy Gannon,Kate Zen,Kate Kenny'。 – Slam