2011-05-15 3 views
1

MySQL 레코드에 적어도 2 개의 유사한 문자열을 표시하는 프로그램이 있습니다. 현재 잘 작동하지만 너무 느린 300K 레코드가 있습니다.mysql에서 중복 문자열 항목을 쿼리하는 방법

예 CONTACT 테이블 항목 : 나는 기록을 얻을 필요가

 
id (int)| name (string) | phone (string) 
----------------------------------------- 
1  | mike   | 081239812345678 
2  | jhon   | 082222212345678 
3  | rudy   | 081237712345678 
4  | lucy   | 081237712345123 
5  | lily   | 081244412345678 

이 "백합 마이크, jhon, 루디와"마지막 전화 번호 숫자 8 (중복) 동일하기 때문에,하지만 기록이 속하는 속하는

내 첫 번째 쿼리 :

내 현재의 방법처럼이 쿼리를 사용하는 것입니다 (다른 기록이 비슷한 8 자리로 끝나는 번호가 없기 때문에) 루시는 무시됩니다에 나는 "myRight"의 값을 얻을 수 있습니다이 쿼리에서

 
"select right(phoner, 8) as myRight 
    , count(*) as totdup 
    from contact 
    group by myRight 
    having totdup > 1"; 
는 나는 세부 사항을 얻기 위해 두 번째 쿼리를 실행합니다

 
"select * from contact where phone like '%$myRight'"; 

내 질문은 내가 300K 기록을 가지고이 걸리기 때문에 과정을 빠르게하는 방법입니다 약 20 분이 쿼리에 대한, 또한 쿼리를 사용하여 쿼리를 단순화하기 위해 찾고 있어요하지만 난 어떻게 해야할지 모르겠다, 나는 지금이 문제에 대한 투쟁을 몇 일 동안, 당신의 도움은 매우 감사하게 될 것입니다.

답변

0

첫 번째 쿼리의 결과 행에 대해 루프를 실행하고 두 번째 쿼리를 각 행마다 한 번씩 실행하는 것처럼 보입니다.

나는 임시 테이블에 첫 번째 결과를두고 다음 아마 더 성능이 향상됩니다 임시 테이블에 인덱스를 넣는

SELECT contact.* FROM contact JOIN temporary 
WHERE right(contact.phoner, 8) = temporary.myRight 

을하는 게 좋을 것.

0

사용중인 MySQL의 버전에 따라이 작동 될 수 있습니다

select * 
from contact 
where RIGHT(phone, 8) IN (
select right(phone, 8) as myRight 
    from contact 
    group by myRight 
    having COUNT(*) > 1 
) 
1

당신이 역순으로 PHONENUMBERS의 (8) 맨 오른쪽 문자를 저장하는 경우 다음
당신의 표는 다음이 필요합니다 필드 :

select right(phone,8) as myRight 
from contact c1 
inner join contract c2 on (left(c1.phonerev,8) = left(c2.phonerev,8) 
          and c1.id <> c2.id) 
group by left(phonerev,8) 
: 당신이 같은 쿼리를 수행 할 수

id (int)| name (string) | phone (string) | phonerev (string) 
---------------------------------------------------- 
1  | mike   | 081239812345678 | 876543218932180 
2  | jhon   | 082222212345678 | 876543212222280 
3  | rudy   | 081237712345678 | 876543217732180 
4  | lucy   | 081237712345123 | 321543217732180 
5  | lily   | 081244412345678 | 876543214442180 

수행하여 쿼리를 통합 할 수 있습니다 당신이 phonerev

에 인덱스를 설정해야합니다 : 그냥 팔을 저장하는 경우

select c1.* 
from contact c1 
inner join contract c2 on (left(c1.phonerev,8) = left(c2.phonerev,8) 
          and c1.id <> c2.id) 

이이 PHONENUMBER

에 인덱스의 사용을 허용한다 가장 오른쪽의 문자를 역순으로 입력하면 쿼리는 다음과 같이됩니다.

select right(phone,8) as myRight 
from contact c1 
inner join contract c2 on (c1.phonerev,8 = c2.phonerev 
          and c1.id <> c2.id) 
group by phonerev; 

어느 쪽이 더 빠릅니다.

0

@ Johan, 당신은 나에게 쿼리 속도를 높이는 좋은 방향을주었습니다. 전화의 오른쪽 8 칸에 새로운 필드를 추가했습니다. 쿼리에서 "right (phone, 8)"을 사용하지 마십시오.

@Will A, 도와 주셔서 감사합니다. 그러나 쿼리가 실제로 현재 솔루션보다 느린 이유를 모르겠습니다.

@LHMathies, 좋은 생각이지만 myRight를 저장하기위한 임시 테이블을 만드는 것은 내 서버/데이터베이스 조건에는 적용 할 수 없습니다.

고맙습니다 ~

관련 문제