2010-07-11 3 views
3

현재 약 2 천만 개의 행이있는 MySQL 테이블이 있으며이를 정리해야합니다. updateTime (삽입 타임 스탬프)가 1 개월 이상인 모든 행을 제거하고 싶습니다.큰 테이블을 빠르게 정리하는 방법은 무엇입니까?

전. 개인적으로 테이블 순서의 변경을 수행하지 않았으므로 데이터는 삽입 된 순서대로 있어야하며 idupdateTime의 두 필드에 UNIQUE 키가 있습니다. 짧은 시간에 어떻게해야합니까?

답변

12

얼마나 많은 다운 타임이 발생할 수 있습니까? 행이 얼마나 큽니까? 몇 명을 삭제 하시겠습니까?

간단히 말하면 행을 삭제하는 것이 테이블에서 할 수있는 가장 비싼 작업 중 하나입니다. 전반적으로 끔찍한 일입니다.

디스크 공간이 필요하지 않고 쿼리가 테이블 크기의 영향을받지 않는 경우 (잘 인덱싱 된 쿼리는 일반적으로 테이블 크기를 무시함) 충분 해.

기회가 있고 오프라인으로 테이블을 가져갈 수 있다면 (그리고 테이블의 좋은 비율을 제거하는 경우) 보관하려는 행을 새 테이블로 복사하고 이전 이름으로 새 이름을 바꾸고 색인을 다시 작성하십시오.

그렇지 않으면, 당신은 꽤 좋은 'ol 삭제와 붙어있어.

12

많은 수의 행을 제거하는 두 가지 방법이 있습니다. 먼저 확실한 방법이있다 :

DELETE FROM table1 WHERE updateTime < NOW() - interval 1 month; 

두 번째 (약간 더 복잡한) 방법은 새 테이블을 만들고 기존 테이블을 계속 절단 할 데이터를 복사 한 다음 다시 행을 복사하는 것입니다. 삭제하기 위해 많은 수의 행 및 유지하고자하는 비교적 적은 수있을 때

CREATE TABLE table2 AS 
SELECT * FROM table1 WHERE updateTime >= NOW() - interval 1 month; 

TRUNCATE table1; 

INSERT INTO table1 
SELECT * FROM table2; 

사용 TRUNCATEWHERE 절과 DELETE보다 훨씬 빠릅니다.

+0

3700 만 개의 행이있는 테이블을 사용해 보았습니다. 200k 행을 삭제해야했습니다. TRUNCATE 방식이 더 빠릅니다. (나는 약 10 분 후에 전통적인 DELETE를 기다리는 것에 지쳤으며, 다른 방법은 약 3 분이 걸렸다.) 좋은 테이블 인 임시 테이블 – Agustin

+0

을 사용했습니다! 내 백업 + 복원의 시간을 줄이는 훌륭한 방법 –

0

제한을 사용하여 삭제를 분할하면 처리 속도가 빨라질 수 있습니다.

10M 행을 삭제해야하고 명령을 실행했습니다. 그것은 몇 시간 동안 결코 응답하지 않았다.

나는 다음 삭제를 분할

(시간의 몇했다) 쿼리를 죽였다.

DELETE from table where id > XXXX limit 10000; 
DELETE from table where id > XXXX limit 10000; 
DELETE from table where id > XXXX limit 10000; 
DELETE from table where id > XXXX limit 10000; 

그런 다음이 문을 파일에 복제하고 명령을 사용했습니다.

mysql> source /tmp/delete.sql 

훨씬 빨랐습니다.

pt 도구와 같은 도구를 사용해 볼 수도 있습니다. 및 태평양 표준시 아카이버.

0

실제로 테이블을 오랫동안 사용할 수 없더라도 '테이블 이름 변경'기술을 사용하여 이전 데이터를 제거 할 수 있습니다.

테이블에 writting 프로세스를 중지하십시오.

rename table tableName to tmpTableName; 
create table tableName like tmpTableName; 
set @currentId=(select max(id) from tmpTableName); 
set @[email protected]+1; 
set @indexQuery = CONCAT("alter table test auto_increment = ", @currentId); 
prepare stmt from @indexQuery; 
execute stmt; 
deallocate prepare stmt; 

테이블에 writting 프로세스를 시작하십시오.

insert into tableName 
select * from tmpTableName; 
drop table; 

올바른 색인에서 tableName에 대한 새로운 삽입이 시작됩니다. 이전 데이터가 올바른 색인에 삽입됩니다.

관련 문제