
我有一個 MyISAM 表,目前包含大約 5400 萬筆記錄,大小為 20 GB。設計這個資料庫時做了錯誤的選擇。我不是資料庫專業人士,但由於該表不斷被寫入並且很少被查詢,因此 InnoDB 似乎是一個更好的選擇。問題是該表必須幾乎始終可供寫入。其中一個欄位是帶有時間戳記的欄位。記錄可以追溯到 5 年前——我只需要保留最近 6 個月的記錄。我嘗試過一些刪除,大約需要20分鐘才能刪除200,000行,在此期間表被鎖定並且無法寫入。有人對如何減少該表的大小而不將其鎖定幾個小時提出建議嗎?有沒有更快的方法來刪除不需要的行?我從未將 MyISAM 表轉換為 InnoDB 表。這是一個漫長的過程嗎?
答案1
我終於有時間重新審視這個項目,為了完整起見,我想發布我最終所做的事情。我相信 DELETE FROM 花費這麼長時間的最初問題與我如何指定要刪除的行有關。我正在使用類似的聲明
DELETE FROM table WHERE starttime < 20150101 limit 200000;
starttime 欄位其實是一個 DATETIME。我最終使用創建了一個新表
CREATE TABLE new_table LIKE existing_table;
然後更改新表的引擎
ALTER TABLE new_table ENGINE=InnoDB;
然後重命名
RENAME TABLE existing_table TO old_table, new_table TO existing_table;
此後,我需要將舊表中 6 個月的資料放入新表中
INSERT INTO existing_table SELECT * FROM old_table WHERE starttime BETWEEN DATE_SUB(NOW(), INTERVAL 6 MONTH) AND NOW();
謝謝馬丁的建議。我是伺服器故障的新手,所以我不確定如何將他的評論標記為答案。
答案2
MyISAM 只適用於 SELECT。 Innodb 有獨立的讀和寫隊列。因此,當您刪除 200,000 行時,表不會被鎖定。表鎖是 MyISAM 在生產環境中的一大限制。在大多數情況下,InnoDB 比 MyISAM 慢,但由於更好的鎖定機制,在某些情況下可以執行得更快; MyISAM 在執行插入/更新時鎖定整個表以供讀取。 InnoDB可以進行行級鎖定,從而允許對錶進行多個並發寫入和讀取
http://kakadba.blogspot.in/2014/02/innodb-vs-myisam.html
將 MyISAM 轉換為 INNODB
你可以逐桌進行
ALTER TABLE table_name ENGINE=InnoDB;
或者您可以嘗試使用腳本一次完成所有操作
https://stackoverflow.com/questions/3856435/how-to-convert-all-tables-from-myisam-into-innodb