2010-07-11 25 views
3

我目前有一個約2000萬行的MySQL表,我需要修剪它。我想刪除updateTime(插入時間戳)超過一個月的每一行如何快速修剪大表?

以前。我沒有親自對錶的順序進行任何更改,因此數據應按其插入的順序進行,並且在兩個字段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; 

使用TRUNCATEDELETE快得多用WHERE條款,當你有大量的行刪除,並且要保持一個相對小的數目。

+0

我試着用一個有370萬行的表。我不得不刪除200k行。 TRUNCATE的方式更快。 (我已經厭倦了大約10分鐘後等待傳統的DELETE,另一種方式花了大約3分鐘)。我用了TEMPORARY表 – Agustin 2013-11-27 19:11:58

+0

這是很好的東西!減少我的備份+恢復時間的好方法 – 2014-04-22 17:22:04

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-tools這樣的工具。和pt-archiver。

0

實際上,即使您不能長時間離線表,仍然可以使用「重命名錶」技術來擺脫舊數據。

停止寫入表的進程。

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; 

開始寫入表的進程。

insert into tableName 
select * from tmpTableName; 
drop table; 

對tableName的新插入將從正確的索引開始;舊數據將被插入到正確的索引中。