MySQL - 刪大量資料效能調整

MySQL - 刪大量資料效能調整

這次要刪除舊有不需要用到的資料,

在原有的幾百萬筆資料,刪除30萬筆資料。靠的是某個欄位的Id值。

使用過不同的方式刪資料,

第一個方式:

delete from TableA where FK_ID in (select ID from Table B);

超級慢,也不知道慢在哪?而且卡住,無法確認行蹤。

後來,發現,因為TableA 資料欄位很多,加上 索引數量龐大,所會導致刪資料很慢,外加,一口氣刪30萬筆的資料,事實關聯的資料可能超過300萬筆,所以可能會等到瘋掉。

改採用第二個方式,試試。

第二個方式:

將TableB ID值倒出來變csv,然後透過取代,變成delete from TableA where FK_ID = ID; 30萬行。

再ssh到linux使用 mysql -uroot -p database < delete.sql;

發現,更慢,雖然不用等那一個長串的SQL,等速度慢到吐血,

我後來實測使用delete from TableA where FK_ID in (ID1,ID2,ID3)

1筆0.06sec,2筆0.15sec,3筆0.22sec,實測50測也差不多0.22sec

發現,in其實不會慢,只是不能in太多,

另外,雖然匯檔使用整個檔案,但實際,mysql可能認知的是30萬行指令,所以可能來來回回會是30萬條來回的連線。

反而不會快到哪,而且每個都以0.15~0.22sec速度,不如一口氣刪N行算了。所以就改方法三

方法三:

使用Java撰寫,單一連線,一口氣撈1000筆,並delete from in 1000筆的方式處理。

速度快很多,我刪30萬筆關聯資料(可能超過百萬以上資料)花費1845507毫秒。

約30.75分鐘。

這還有包含先刪掉一堆跟刪除無法有索引,日後再加回就好。

發現要做這種事,先從未上線的Table開始進行處理,刪除再切換成上線,或許會避免卡lock

覺得要研究,有什麼很好的刪除方式,

但發現我在本機匯檔速度相檔的快速。(莫非跟我SSD的主硬碟有關?)

或許刪除沒這麼容易,但大量新增就沒這麼慢,不過700萬筆資料也是要花一個半到兩個小時。用insert into tableA () select * from tableB

在想,用insert into A() select * form B這樣的方式,可能由於資料龐大,佔用了記憶體,反而不會快 

反而我每200~1000筆讀一次,寫進檔案,再由匯檔指令送入,反而更快。

可能使用檔案指令只是送出,並沒 select 的動作,反而花的時間比較少

 

最後總結:

1. delete from table in 的數量過多,會慢

2.索引過多會慢

3.匯檔,檔案裡的資料一筆一筆刪除數量太多,也會慢

4.刪除的欄位個數與長度過多,也會慢

5.關聯的筆數多,也會慢。

慢到,搞到我快吐血。