2009-12-07 12 views
3

Je continue d'obtenir ces erreurs lorsque j'essaie de supprimer des lignes d'une table. Le cas particulier ici est que je peux exécuter 5 processus en même temps.La suppression de lignes entraîne un délai de verrouillage

La table elle-même est une table Innodb avec ~ 4,5 millions de lignes. Je n'ai pas d'index sur la colonne utilisée dans ma clause WHERE. D'autres indices fonctionnent comme prévu. Cela se fait dans une transcation, d'abord je supprime les enregistrements, puis j'insère les enregistrements de remplacement, et seulement si tous les enregistrements sont insérés si la transaction est validée.

Message d'erreur:

Query error: Lock wait timeout exceeded; try restarting transaction while executing DELETE FROM tablename WHERE column=value

Ne serait-il aider à créer un index sur la colonne référencée ici? Dois-je verrouiller explicitement les lignes?

J'ai trouvé quelques informations supplémentaires à la question #64653 mais je ne pense pas que cela couvre complètement ma situation.

Est-il certain que c'est l'instruction DELETE qui provoque l'erreur, ou pourrait-il s'agir d'autres instructions de la requête? L'instruction DELETE est la première, donc cela semble logique mais je ne suis pas sûr.

Répondre

3

Un index serait certainement utile. Si vous essayez de remplacer les enregistrements supprimés, je vous recommande de modifier votre requête pour utiliser une mise à jour au lieu d'une suppression suivie d'une instruction INSERT, si possible:

INSERT INTO tableName SET 
column2 = 'value2' 
WHERE column = value 
ON DUPLICATE KEY UPDATE 
column2 = 'value2' 
+0

Une mise à jour n'est pas possible. Les enregistrements de remplacement pourraient être moins/plus. A quoi sert l'index? Diminuer le temps d'exécution, à son tour diminuer la probabilité de temps de verrouillage se produire? –

+1

Ah, je vois. Vous l'avez cloué en ce qui concerne la réduction du temps d'exécution. Avec 4,5 millions de lignes, je suppose que vous rencontrez des requêtes lentes. Essayez d'exécuter un exemple d'instruction select basée sur l'un de vos identifiants de colonne pour voir à quel point il est lent de récupérer vos enregistrements sans index. Puis revenir en arrière et ajouter un index et l'utiliser pour une comparaison. Si la colonne est un CHAR/VARCHAR assez grand, vous pouvez réduire certains frais en n'utilisant qu'une fraction du champ pour votre index, c'est-à-dire ** CREATE INDEX partial_idx ON nomtable (column (10)) ** pour n'utiliser que les 10 premiers caractères comme valeur de votre index. –

+0

Cela fonctionne plutôt bien avec ce changement. Je vous remercie! –

1

Un index permet sans aucun doute. J'ai déjà travaillé sur une base de données contenant des données utilisateur. Il y avait parfois un problème avec le front Web et la suppression de l'utilisateur. Au cours de la journée, cela a bien fonctionné (même si cela a pris assez longtemps). Mais en fin d'après-midi, il arrivait parfois que le serveur DB soit surchargé en raison du traitement de fin de journée. Whacked un index sur la colonne affectée et tout s'est bien passé à partir de là.

+0

Oui, dans mon cas c'était la parallélisation qui a fait que cette erreur se produise. Lors de l'exécution d'une seule instance, cela n'a jamais été un problème. –