2017-10-09 74 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