Tout d'abord, si vous utilisez par défaut le moteur de stockage InnoDB de MySQL, il n'y a aucun moyen de mettre à jour les données sans verrous de ligne, sauf en définissant le niveau d'isolation des transactions sur READ UNCOMMITTED en exécutant
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
Cependant, je ne pense pas que le comportement de la base de données soit ce que vous attendez puisque la lecture sale est autorisée dans ce cas. READ UNCOMMITTED est rarement utile dans la pratique.
Pour compléter la réponse de @Tim, c'est en effet une bonne idée d'avoir un index unique sur la colonne utilisée dans la clause where. Cependant, veuillez également noter qu'il n'y a aucune garantie absolue que l'optimiseur choisira éventuellement un tel plan d'exécution en utilisant l'index créé. Cela peut fonctionner ou ne pas fonctionner, selon le cas.
Dans votre cas, vous pouvez diviser la transaction longue en plusieurs transactions courtes. Au lieu de mettre à jour des millions de lignes en une seule fois, il serait préférable de ne scanner que des milliers de lignes à chaque fois. Les verrous X sont libérés lorsque chaque transaction courte est validée ou annulée, ce qui donne aux mises à jour simultanées la possibilité d'aller de l'avant.
Soit dit en passant, je suppose que votre lot a une priorité inférieure à celle des autres processus en ligne, il pourrait donc être programmé en dehors des heures de pointe pour minimiser davantage l'impact.
PS Le verrou IX n'est pas sur l'enregistrement lui-même, mais attaché à l'objet de table de granularité supérieure. Et même avec le niveau d'isolement de la transaction REPEATABLE READ, il n'y a pas de verrouillage d'espace lorsque la requête utilise un index unique.