2014-07-20 7 views
0

mysql 데이터베이스의 중복 항목을 모두 삭제하고 싶습니다.Mysql - 테이블의 중복 항목을 삭제하는 것은 여러 열에 달려 있습니다.

웹에서 많은 솔루션을 발견했지만 모든 경우에 1 열을 조회 할 때만 쿼리가 작동했습니다.

제 경우에는 가능한 한 많이 실행되는 1 행 이상의 쿼리가 필요합니다. 테이블의 크기는 500MB로 6 백만 개가 넘습니다.

id name status email 
---------------------------- 
x Mark 1  [email protected] 
x Anna 1  [email protected] 
x Mark 0  [email protected] 
x Mark 1  [email protected] 

지금 무슨 일이 일어날해야

내 표 (exampe)? 나는이 같은 쿼리가 필요합니다 (== 이름, 상태 == 상태, 이메일 == 이메일 이름)

가 삭제 * MY_TABLE 곳에서를

표를보고있다이 쿼리를 실행 예 :

id name status email 
---------------------------- 
x Mark 1  [email protected] 
x Anna 1  [email protected] 
x Mark 0  [email protected] 

이름, 상태 및 전자 메일 필드가 다른 항목과 동일하므로 마지막 항목이 삭제되었습니다. 어떤 경우에는 동일한 데이터가있는 20 개 이상의 데이터가 삭제되어야하므로 하나만 남아있게됩니다.

현재 나는 PHP 스크립트로 안좋은 해결책을 가지고 있습니다. 나는 각 행에 동일한 데이터를 찾고 삭제할 것입니다. 작동해야하지만 너무 느린 것 같습니다 ... 아마도 시간당 5.000 개 항목을 생각합니다 ...

더 나은 방법으로 문제를 해결할 수있는 방법을 알고 계십니까?

답변

2

내 제안은 테이블을 자르고 데이터를 다시 삽입하는 방법을 사용하는 것입니다. 다음과 같이 입력하십시오 :

create temporary table temp as 
    select min(id) as id, name, status, email 
    from mytable 
    group by name, status, email; 

truncate table mytable; 

insert into mytable(id, name, status, email) 
    select id, name, status, email 
    from temp; 

삭제 작업을 수행하는 것은 비용이 많이 듭니다. 이렇게하기로 결정하면, 나는 id의 인덱스와 같은 임시 테이블을 만들고 사용합니다 :

delete m 
    from mytable m left join 
     temp 
     on m.id = temp.id 
    where temp.id is null; 

당신은 일괄이 실행 (예 : limit 10000으로) 제한 절을 사용할 수 있습니다.

+0

빠른 솔루션에 감사드립니다. 테스트를 위해 데모 테이블을 사용하여 첫 번째 쿼리를 테스트했는데 이것이 매력처럼 작동합니다. – TJR

+0

은 고유 한 이름, 상태, 이메일을 선택하지 않았습니까? 이것으로 0 – VeNoMiS

+0

@VeNoMiS에서 시퀀스를 다시 시작할 수 있습니다. . . 나는 당신이 "더 나은"것을 의미하는지 모르겠습니다. '뚜렷한 선택'과'그룹별로'비슷한 성능을 가져야합니다. 그리고'id '를 재 할당 할 이유가 없습니다. 물론, OP가 그들을 재 할당하기를 원한다면, 첫 번째 해결책을 위해 임시 테이블에 'id'가 필요하지 않습니다. –

관련 문제