Mysql
如何提高 InnoDB DELETE 性能?
所以我有這個審計表(跟踪我數據庫中任何表的操作):
CREATE TABLE `track_table` ( `id` int(16) unsigned NOT NULL, `userID` smallint(16) unsigned NOT NULL, `tableName` varchar(255) NOT NULL DEFAULT '', `tupleID` int(16) unsigned NOT NULL, `date_insert` datetime NOT NULL, `action` char(12) NOT NULL DEFAULT '', `className` varchar(255) NOT NULL, PRIMARY KEY (`id`), KEY `userID` (`userID`), KEY `tableID` (`tableName`,`tupleID`,`date_insert`), KEY `actionDate` (`action`,`date_insert`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1
我需要開始歸檔過時的項目。該表已增長到大約 5000 萬行,因此我刪除行的最快方法是一次刪除一個表(基於
tableName
)。這工作得很好,但在一些寫繁重的表上,它不會完成。
delete
我的查詢刪除了對 tupleID/tableName 組合具有關聯操作的所有項目:DELETE FROM track_table WHERE tableName='someTable' AND tupleID IN ( SELECT DISTINCT tupleID FROM track_table WHERE tableName='someTable' AND action='DELETE' AND date_insert < DATE_SUB(CURDATE(), INTERVAL 30 day) )
我讓它在我的伺服器上執行了 3 天,但它從未完成最大的表。解釋輸出(如果我將刪除切換為選擇:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | | 1 | PRIMARY | track_table | ref | tableID | tableID | 257 | const | 3941832 | Using where | | 2 | DEPENDENT SUBQUERY | track_table | ref | tableID,actionDate | tableID | 261 | const,func | 1 | Using where; Using temporary |
因此,我認為 400 萬行不應該需要 3 天才能刪除。我將 innodb_buffer_pool_size 設置為 3GB,並且伺服器未設置為使用 one_file_per_table。還有哪些其他方法可以提高 InnoDB 刪除性能?(在 Mac OSX 上執行 MySQL 5.1.43)
您可以批量刪除數據。
在 SQL Server 中,語法是
delete top X
表中的行。然後,您在一個循環中執行此操作,每個批次都有一個事務(當然,如果您有多個語句),因此要保持事務簡短並僅在短時間內保持鎖定。在 MySQL 語法中:
DELETE FROM userTable LIMIT 1000
對此有一些限制(例如,不能
LIMIT
在帶有連接的刪除中使用),但在這種情況下,您可能可以這樣做。當涉及到複製時,使用
LIMIT
with還有一個額外的危險;DELETE
刪除的行有時在從屬設備上的刪除順序與在主設備上的刪除順序不同。