2014-04-10 5 views
4

소리로 이름이 일치하는 연락처 테이블에서 모든 중복 된 이름을 찾고 싶습니다. 예 : Rita 또는 Reeta, Microsoft 또는 Microsift, Mukherjee 또는 Mukherji비슷한 소리로 레코드 받기

가 나는 쿼리 아래 사용했다 :

SELECT contacts.id 
FROM contacts 
INNER JOIN (
    SELECT first_name, last_name, count(*) AS rows 
    FROM contacts 
    WHERE deleted = 0 
    GROUP BY SOUNDEX(first_name), SOUNDEX(last_name) 
    HAVING count(rows) > 1 
) AS p 
WHERE contacts.deleted = 0 
AND p.first_name SOUNDS LIKE contacts.first_name 
AND p.last_name SOUNDS LIKE contacts.last_name 
ORDER BY contacts.date_entered DESC 

위의 쿼리는 올바른 결과를 제공하지만, 많은 기록이있을 때 시간이 많이 걸립니다.

+0

그리고 그렇게됩니다. '유사하게 들릴 것'이 빠른 방법으로 해결 될 수 없기 때문에 문제를 신속하게 해결할 수 없습니다. 따라서'SOUNDEX'가 느리고 전체 쿼리도 마찬가지입니다. –

+0

SOUNDEX를 사용하는 것 외의 다른 방법이 있습니다. – user3286692

+0

"비슷한"문자열을 확인하려면? 아닙니다. 그러나 "비슷한 소리"라는 용어를 간소화 할 수 있다면 –

답변

0

SOUNDEX()보다 나은 (네이티브) 접근 방식을 알지 못합니다. 느린 이유는 그것이 함수이기 때문에 값을 계산하고 거기에서 작업하기 위해 모든 레코드를 처리해야하기 때문입니다. 이 문제를 해결하려면 결과를 테이블에 직접 저장하는 것이 좋습니다. 나는 MySQL의에서 이러한 기능을 가진 경험이 없지만 documentation에 따라 이미 이러한 값을 미리 계산이 줄 경우 따라서

[...] AND SOUNDEX(p.first_name) = SOUNDEX(contacts.first_name) [...] 

WHERE 절을 변환 할 수 있습니다 것 같다 (및 색인!) 검색을 일치하는 레코드에 대한 속도가 급격히 빨라야합니다!

귀하의 질문을 파악하는 데 어려움이 있습니다. 나는 당신이 그 곳에서 HAVING COUNT(*) > 1을 필요로하지 않는다고 생각합니다. 그럼에도 불구하고 그룹을 어떻게 만들고 싶은지 혼란 스럽습니다.

당신이 뭔가를 원하십니까 : 당신이 다음 optmize 등 first_name_soundex은 SOUNDEX (FIRST_NAME)의 결과를 보유하고

SELECT c1.id as contact_id, 
     c2.id as similar_id 
    FROM contacts c1 
    JOIN contacts c2 
    ON c2.id <> c1.id 
    AND c2.deleted = 0 
    AND c2.first_name_soundex = c1.first_name_soundex 
    AND c2.last_name_soundex = c1.last_name_soundex 
WHERE c1.deleted = 0 
ORDER BY c1.date_entered DESC 

로 색인 할 때 위의 제안 수 있기

SELECT c1.id as contact_id, 
     c2.id as similar_id 
    FROM contacts c1 
    JOIN contacts c2 
    ON c2.id <> c1.id 
    AND c2.deleted = 0 
    AND SOUNDEX(c2.first_name) = SOUNDEX(c1.first_name) 
    AND SOUNDEX(c2.last_name) = SOUNDEX(c1.last_name) 
WHERE c1.deleted = 0 
ORDER BY c1.date_entered DESC 

덮기 색인이 deleted, first_name_soundex, last_name_soundex에 있고 싶을 수도 있습니다. (AFAIK MySQL은 필터링 된 인덱스를 지원하지 않습니다. 그렇지 않으면 인덱스를 deleted = 0으로 제한 할 수 있습니다).

0

SOUNDEX는 매우 제한된 유틸리티 (IMHO)입니다. 극단적 인 예 ...

SELECT SOUNDEX('cholmondley'); 
+------------------------+ 
| SOUNDEX('cholmondley') | 
+------------------------+ 
| C4534     | 
+------------------------+ 

SELECT SOUNDEX('chumleigh'); 
+----------------------+ 
| SOUNDEX('chumleigh') | 
+----------------------+ 
| C542     | 
+----------------------+