Então, eu tenho esta tabela de auditoria (rastreia ações em qualquer tabela no meu banco de dados):
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
e preciso começar a arquivar itens desatualizados. A tabela cresceu para cerca de 50 milhões de linhas, portanto, a maneira mais rápida de excluir as linhas era excluí-la de uma tabela por vez (com base em tableName
).
Isso funciona muito bem, mas em algumas tabelas com muita gravação, ela não será concluída. Minha consulta exclui todos os itens que têm uma delete
ação associada em uma combinação 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)
)
Eu deixei isso rodar no meu servidor por 3 dias e ele nunca foi concluído para a maior tabela. A saída de explicação (se eu alternar a exclusão para selecionar:
| 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 |
Então, 4 milhões de linhas não devem levar três dias para serem excluídos, eu acho. Eu tenho meu innodb_buffer_pool_size definido como 3 GB e o servidor não está definido para usar one_file_per_table. De que outras maneiras posso melhorar o desempenho de exclusão do InnoDB? (Executando o MySQL 5.1.43 no Mac OSX)