Entonces tengo esta tabla de auditoría (rastrea acciones en cualquier tabla de mi base de datos):
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
y necesito comenzar a archivar elementos obsoletos. La tabla ha crecido a aproximadamente 50 millones de filas, por lo que la forma más rápida en que podía eliminar las filas era eliminarla de una tabla a la vez (según tableName
).
Esto funciona bastante bien, pero en algunas de las tablas que requieren mucha escritura, no se completará. Mi consulta elimina todos los elementos que tienen una delete
acción asociada en una combinación 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)
)
Dejé que esto se ejecute en mi servidor durante 3 días y nunca se completó para la tabla más grande. La salida de explicación (si cambio la eliminación para seleccionar:
| 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 |
Entonces, 4 millones de filas no deberían tomar 3 días para eliminar, creo. Tengo mi innodb_buffer_pool_size establecido en 3GB, y el servidor no está configurado para usar one_file_per_table. ¿De qué otras formas puedo mejorar el rendimiento de eliminación de InnoDB? (Ejecutando MySQL 5.1.43 en Mac OSX)