使用MySQL改进查找模糊重复项

使用MySQL改进查找模糊重复项,mysql,fuzzy-search,soundex,Mysql,Fuzzy Search,Soundex,我有一个因操作员输入错误而吸引重复记录的名称、公司或产品表 我正在尝试创建一个工具来管理这个问题。它不会是一个高流量页面,但在构建记录集时,它仍然不应该杀死数据库。我有一个查询,需要几分钟来处理(太长了): 但这些似乎远非如此: Daniel Cope | Dan Willis & Obie David Williams | David Holmes 有没有一种更快、更不模糊的方法来解决这个问题?你的问题有两个部分 首先,为什么您的查询速度慢 其次,为什么SOUNDEX()有太多的假阳

我有一个因操作员输入错误而吸引重复记录的名称、公司或产品表

我正在尝试创建一个工具来管理这个问题。它不会是一个高流量页面,但在构建记录集时,它仍然不应该杀死数据库。我有一个查询,需要几分钟来处理(太长了):

但这些似乎远非如此:

Daniel Cope | Dan Willis & Obie
David Williams | David Holmes

有没有一种更快、更不模糊的方法来解决这个问题?

你的问题有两个部分

首先,为什么您的查询速度慢

其次,为什么
SOUNDEX()
有太多的假阳性匹配?有没有比
SOUNDEX()
更好的接近匹配的方法

让我们一次拿一个

首先,让我们尝试加快此查询的速度。让我们首先在标准SQL中重新构建它(消除旧式连接)

然后索引它

然后运行此查询:

    SELECT 
    tab1.id as id1, 
    tab1.creative as creative1, 
    tab2.id as id2, 
    tab2.creative as creative2 
FROM creatives AS tab1 
JOIN creatives tab2 
  ON (
          tab1.id < tab2.id   /* don't duplicate pairs a/b b/a */  
      AND tab1.compare_hash = tab2.compare_hash
     )
完成此比较散列后,可以运行相同的自连接查询

(我试过用Levenshein距离来表示这种情况。问题是,对于不同长度的字符串对,要获得一致的相同度量。)


要做到这一点,需要一些混乱和一些肘部润滑脂。您在编程中投入了多少编程,这取决于有一种更好的方法,称为Levenshtein distance()。你可以用谷歌搜索并找到运行它的代码。不幸的是,它不是更快。更快:可能不是。不那么模糊:莱文施泰因?MySQL中的选项是有限的,您可能希望查询和检索数据集,然后让MySQL继续工作,然后在应用程序中进行比较。
Daniel Cope | Dan Willis & Obie
David Williams | David Holmes
SELECT 
    tab1.id as id1, 
    tab1.creative as creative1, 
    tab2.id as id2, 
    tab2.creative as creative2 
FROM creatives AS tab1 
JOIN creatives tab2 
  ON (
          tab1.id < tab2.id   /* don't duplicate pairs a/b b/a */  
      AND SOUNDEX(tab1.creative)= SOUNDEX(tab2.creative) 
     )
UPDATE creatives 
   SET compare_hash = SOUNDEX(creative)
    SELECT 
    tab1.id as id1, 
    tab1.creative as creative1, 
    tab2.id as id2, 
    tab2.creative as creative2 
FROM creatives AS tab1 
JOIN creatives tab2 
  ON (
          tab1.id < tab2.id   /* don't duplicate pairs a/b b/a */  
      AND tab1.compare_hash = tab2.compare_hash
     )
UPDATE creatives  SET compare_hash = LOWER(creative);
UPDATE creatives  SET compare_hash = REPLACE(compare_hash , ' ', '');
UPDATE creatives  SET compare_hash = REPLACE(compare_hash , 'a', '');
UPDATE creatives  SET compare_hash = REPLACE(compare_hash , 'e', '');
UPDATE creatives  SET compare_hash = REPLACE(compare_hash , 'i', '');
UPDATE creatives  SET compare_hash = REPLACE(compare_hash , 'o', '');
UPDATE creatives  SET compare_hash = REPLACE(compare_hash , 'u', '');