J'écris une application qui doit éliminer un grand nombre de mises à jour de la base de données pendant une longue période, et je suis resté coincé sur la façon d'optimiser la requête. Actuellement, j'utilise INSERT INTO ... VALUES (..), (..) ON DUPLICATE KEY UPDATE
, qui fonctionne pour regrouper toutes les valeurs dans une seule requête, mais s'exécute de manière atroce lentement sur de grandes tables. Je n'ai jamais vraiment besoin d'insérer de lignes.
D'autres approches que j'ai vues consistent à mettre à jour à l'aide de SET value = CASE WHEN...
(qui serait difficile à générer en raison de la façon dont je construis les requêtes, et je ne suis pas sûr des performances de CASE
pour des centaines / milliers de clés), et simplement à plusieurs concaténations mises à jour. L'un ou l'autre serait-il plus rapide que ma méthode actuelle?
Cela me déconcerte que, pour autant que je sache, il n'y a pas de moyen idiomatique et efficace de le faire dans MySQL. S'il n'y a vraiment pas de moyen plus rapide que cela ON DUPLICATE KEY
, cela vaudrait-il la peine de passer à PostgreSQL et d'utiliser sa UPDATE FROM
syntaxe?
Toutes autres suggestions sont également grandement appréciées!
Edit: voici l'un des tableaux qui est mis à jour fréquemment. J'ai supprimé les noms de colonnes car ils n'étaient pas pertinents.
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;
Réponses:
Puisque vous utilisez des
InnoDB
tables, l'optimisation la plus évidente serait de regrouper plusieursUPDATE
s dans une transaction.Avec
InnoDB
, étant un moteur transactionnel, vous payez non seulement pourUPDATE
lui - même, mais aussi pour tous les frais généraux transactionnels: gestion du tampon de transaction, journal des transactions, vidage du journal sur le disque.Si vous êtes logiquement à l'aise avec l'idée, essayez de regrouper 100-1000
UPDATE
s à la fois, chaque fois emballé comme ceci:Inconvénients possibles:
UPDATE
s, vous pouvez donc également souhaiterla source