2014-02-10 4 views
0

나는 약 1 억 줄의 MyISAM 테이블을 3 개 가지고 있습니다. 내가하는 (지역, ID)을 위해 7 일 이상 전에 타임 스탬프에 관련된 모든 행을 삭제할 많은 양의 줄 삭제

3GB

에 대해

Table1 structure is (region, id,timestamp) 
Table2 structure is (region, id, data1, data2) 
Table3 structure is (region, id, data3, data4) 

Table1 PK is (region,id) 
Table2 PK is (region,id,data1) 
Table3 PK is (region,id,data3) 

각 테이블의 크기입니다. (테이블의 약 15 %)

두 가지 방법을 시도했지만 어느 것도 만족하지 못했습니다.

  • 처음에는 JOIN을 사용하여 여러 개의 다중 테이블 삭제를 수행했습니다. 12 시간 후, 그것은 아직도 달리고 있었다.
  • 두 번째로 첫 번째 테이블에서 select를 수행하여 삭제해야하는 모든 (region, id)을 가져온 다음 각 테이블에서 10,000 개의 배치를 삭제합니다. 이 구문은 기본적으로 다음과 같습니다. DELETE FROM table WHERE (region, id) IN ((region1, id1), (region1, id2) ...)이 방법은 매우 느린 것 같습니다 (요청 당 60s). EXPLAIN, PK는 사용되지 않습니다 (!!).

나는 table2와 table3에서 인덱스를 비활성화하려고 시도했지만 그 쿼리의 성능을 크게 향상시키지 못했습니다.

또한 쿼리에 너무 많은 시간이 걸리면 동시에이 테이블에서 다른 작업 (INSERT 만)을 수행 할 수 있도록 작업중인 테이블을 잠그지 않도록하고 싶습니다.

그래서 제안 사항이 있습니까? 아니면이를 수행하기위한 모범 사례가 있습니까?

+0

오프라인 작업을 수행하고 작업 준비가 완료되면 서버로 이동할 수 있습니까? – malta

+0

"이 작업을 오프라인으로 수행하는 것"이 ​​무슨 뜻인지 잘 모르겠습니다. – Nisalon

답변

0

한 번에 하나의 레코드를 삭제하는 데 사용할 수있는 커서를 사용해 보았습니까? 예 :

DELIMITER $$ 
DROP PROCEDURE IF EXISTS delete_using_cursor$$ 
CREATE PROCEDURE delete_using_cursor() 
BEGIN 
declare done int default false; 
declare pk int; 
declare c cursor for select [id] from [table] where [conditions]; 
declare continue handler for not found set done = true; 
set @strSQL = 'delete from [table] where [id] = ?'; 
prepare stmt from @strSQL; 
open c; 
read_loop: loop 
    fetch c into pk; 
    if done then 
    leave read_loop; 
    end if; 
    set @pk = pk; 
    execute stmt using @pk; 
end loop; 
close c; 
deallocate prepare stmt; 
END $$ 
DELIMITER ;