2014-02-10 82 views
0

我有3個表MyISAM表,每個約100萬行。刪除大量的行

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) 

每個表的大小爲約的3Gb

我想刪除它(區,ID)被關聯到一個時間戳超過7天前的所有行。 (約表的15%)

我試過兩種方法,它們都不令人滿意。

  • 首先我做了一些使用JOIN的多表刪除。 12小時後,它仍在運行。
  • 其次,我在第一張桌子上做了一個選擇,以獲取我必須刪除的所有(區域,ID),然後在每個桌子上以10,000批次進行刪除。爲此,語法基本上是:DELETE FROM table WHERE(region,id)IN((region1,id1),(region1,id2)...)這個方法看起來非常慢(每個請求60s),而且當我一個解釋,PK不使用(!!)。

我試圖禁用表2和表3上的索引,但似乎並沒有大幅度提高這些查詢的性能。此外,如果查詢需要太多時間,我希望能夠不鎖定它正在處理的表,以便我可以同時對此表執行其他操作(僅限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 ;