我目前有一個約2000萬行的MySQL表,我需要修剪它。我想刪除updateTime
(插入時間戳)超過一個月的每一行如何快速修剪大表?
以前。我沒有親自對錶的順序進行任何更改,因此數據應按其插入的順序進行,並且在兩個字段id
和updateTime
之間有一個UNIQUE
密鑰。我會如何在短時間內做這件事?
我目前有一個約2000萬行的MySQL表,我需要修剪它。我想刪除updateTime
(插入時間戳)超過一個月的每一行如何快速修剪大表?
以前。我沒有親自對錶的順序進行任何更改,因此數據應按其插入的順序進行,並且在兩個字段id
和updateTime
之間有一個UNIQUE
密鑰。我會如何在短時間內做這件事?
你會產生多少停機時間?行數有多大?你有多少人刪除?
簡而言之,刪除行是您可以對錶執行的最昂貴的操作之一。整體而言,這只是一件可怕的事情。
如果您不必這樣做,並且您有磁盤空間,並且您的查詢不受表大小的影響(良好索引的查詢通常會忽略表大小),那麼您可以保持良好足夠單獨。
如果您有機會可以離線使用表格(並且您正在移除表格的很大比例),那麼您最好的辦法是將要保留的行復制到新表格中,舊的名稱,將新名稱重命名爲舊名稱,然後重新創建索引。
否則,你幾乎堅持好ol刪除。
有兩種方法可以刪除大量的行。首先,有明顯的方法:
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;
使用TRUNCATE
比DELETE
快得多用WHERE
條款,當你有大量的行刪除,並且要保持一個相對小的數目。
以限制方式拆分刪除可能會加快此過程;我不得不刪除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。
實際上,即使您不能長時間離線表,仍然可以使用「重命名錶」技術來擺脫舊數據。
停止寫入表的進程。
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的新插入將從正確的索引開始;舊數據將被插入到正確的索引中。
我試着用一個有370萬行的表。我不得不刪除200k行。 TRUNCATE的方式更快。 (我已經厭倦了大約10分鐘後等待傳統的DELETE,另一種方式花了大約3分鐘)。我用了TEMPORARY表 – Agustin 2013-11-27 19:11:58
這是很好的東西!減少我的備份+恢復時間的好方法 – 2014-04-22 17:22:04