Estoy escribiendo una aplicación que necesita eliminar una gran cantidad de actualizaciones de la base de datos durante un período prolongado de tiempo, y me he quedado atascado en cómo optimizar la consulta. Actualmente estoy usando INSERT INTO ... VALUES (..), (..) ON DUPLICATE KEY UPDATE
, que funciona para agrupar todos los valores en una consulta, pero se ejecuta de manera insoportablemente lenta en tablas grandes. En realidad, nunca necesito insertar filas.
Otros enfoques que he visto son actualizar usando SET value = CASE WHEN...
(lo cual sería difícil de generar debido a la forma en que estoy construyendo las consultas, y no estoy seguro sobre el rendimiento de CASE
cientos / miles de claves), y simplemente concatenado múltiples actualizaciones ¿Alguno de estos sería más rápido que mi método actual?
Me desconcierta que, por lo que puedo ver, no hay una forma idiomática y eficiente de hacer esto en MySQL. Si realmente no hay una forma que sea más rápida ON DUPLICATE KEY
, ¿valdría la pena cambiar a PostgreSQL y usar su UPDATE FROM
sintaxis?
¡Cualquier otra sugerencia también es muy apreciada!
Editar: aquí hay una de las tablas que se actualiza con frecuencia. Eliminé los nombres de columna debido a que son irrelevantes.
CREATE TABLE IF NOT EXISTS `table` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`a` bigint(20) unsigned NOT NULL DEFAULT '0',
`b` bigint(20) unsigned NOT NULL DEFAULT '0',
`c` enum('0','1','2') NOT NULL DEFAULT '0',
`d` char(32) NOT NULL,
-- trimmed --
PRIMARY KEY (`id`),
KEY `a` (`a`),
KEY `b` (`b`),
KEY `c` (`c`),
KEY `d` (`d`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Respuestas:
Como está utilizando
InnoDB
tablas, la optimización más obvia sería agrupar múltiplesUPDATE
correos electrónicos en una transacción.Al
InnoDB
ser un motor transaccional, usted paga no solo porUPDATE
sí mismo, sino también por todos los gastos generales transaccionales: administrar el búfer de transacciones, el registro de transacciones, vaciar el registro al disco.Si está lógicamente cómodo con la idea, intente agrupar 100-1000
UPDATE
s a la vez, cada vez envuelto así:Posibles inconvenientes:
UPDATE
s, por lo que también puede querer tener un tiempo de esperafuente