Utilisation d'une requête préparée volonté réduire la charge CPU du processus mysqld comme le suggèrent DaveRandom et StevenVI. Cependant, dans ce cas, je doute que l'utilisation de requêtes préparées ait un impact matériel sur votre temps d'exécution. Le problème que vous rencontrez est que vous essayez de mettre à jour 100K lignes dans le fichier songs
et cela va impliquer beaucoup d'E/S physiques sur votre sous-système de disque physique. Ce sont ces délais physiques (disons ~10 mSec par PIO) qui domineront les durées d'exécution. Des facteurs tels que le contenu de chaque ligne, le nombre d'index que vous utilisez sur la table (en particulier ceux qui impliquent un chemin d'accès) se mêleront à ce mélange.
Les coûts réels de l'unité centrale pour la préparation d'une simple déclaration telle que
UPDATE songs SET treepath="some treepath" WHERE id=12345;
sera perdue dans ce délai d'E/S physique global, et l'importance relative de ce délai dépendra matériellement de la nature du sous-système physique dans lequel vous stockez vos données : un simple disque SATA ; un disque SSD ; certains NAS avec de grandes mémoires cache et un support SSD ...
Vous devez repenser votre stratégie globale, en particulier si vous utilisez également l'option songs
en même temps qu'une ressource pour les demandes interactives par le biais d'une interface web. La mise à jour de 100 000 lignes va prendre un certain temps - moins si vous mettez à jour 100 000 lignes sur 100 000 dans l'ordre de stockage, car cela sera plus conforme à l'organisation du MYD et la mise en cache en écriture sera meilleure ; plus si vous mettez à jour 100 000 lignes dans un ordre aléatoire sur 1 million de lignes, où le nombre de PIO sera beaucoup plus élevé.
Dans ce cas, les performances globales de votre D/B vont se dégrader fortement.
-
Souhaitez-vous minimiser l'impact sur l'utilisation parallèle de votre base de données ou essayez-vous simplement d'effectuer cette opération par lots avec d'autres services hors ligne ?
-
Votre objectif est-il de minimiser le temps total écoulé ou de le garder raisonnablement court sous réserve d'une certaine contrainte d'impact global, ou même simplement de terminer sans mourir ?
Je pense que vous avez deux approches raisonnables : (i) faire cela comme une activité de lot appropriée avec le D/B hors ligne pour d'autres services. Dans ce cas, vous voudrez probablement verrouiller la table et mettre entre parenthèses les mises à jour avec ALTER TABLE ... DÉSACTIVER/ACTIVER LES CLÉS. (ii) procéder à une mise à jour au compte-gouttes avec des ensembles de mises à jour beaucoup plus petits et un délai entre chaque ensemble pour permettre à la base de données de se décharger sur le disque.
Quoi qu'il en soit, je diminuerais la taille des lots. Le multi_query optimise essentiellement les têtes RPC impliquées dans l'appel à mysqld hors processus. Un lot de 10, par exemple, réduit cela de 90%. Vous avez des rendements décroissants après cela - en particulier si les mises à jour sont intensives en E/S physiques.