web-dev-qa-db-fra.com

Quelles sont les différences pratiques entre `REPLACE` et` INSERT ... ON DUPLICATE KEY UPDATE` dans MySQL?

Ce dont j'ai besoin, c'est de définir les valeurs de tous les champs d'un enregistrement avec une clé particulière (la clé est composite en fait), en insérant l'enregistrement s'il n'y a pas encore d'enregistrement avec une telle clé.

REPLACE semble être censé faire le travail, mais en même temps sa page de manuel suggère INSERT ... ON DUPLICATE KEY UPDATE .

Que dois-je mieux choisir et pourquoi?

Le seul "effet secondaire" de REPLACE qui me vient à l'esprit est qu'il incrémenterait les valeurs d'auto-incrémentation (heureusement, je n'en utilise pas) pendant que INSERT ... ON DUPLICATE KEY UPDATE probablement pas. Quelles sont les autres différences pratiques à prendre en compte? Dans quels cas particuliers REPLACE peut-il être préféré à INSERT ... ON DUPLICATE KEY UPDATE et vice versa?

63
Ivan

REPLACE effectue en interne une suppression puis une insertion. Cela peut provoquer des problèmes si vous avez une contrainte de clé étrangère pointant sur cette ligne. Dans cette situation, le REPLACE pourrait échouer ou pire: si votre clé étrangère est définie pour la suppression en cascade, le REPLACE entraînera la suppression des lignes des autres tables. Cela peut se produire même si la contrainte a été satisfaite avant et après l'opération REPLACE.

En utilisant INSERT ... ON DUPLICATE KEY UPDATE évite ce problème et est donc préférable.

98
Mark Byers

Pour répondre à la question en termes de performances, j'ai fait un test en utilisant les deux méthodes

Remplacer en implique:
1.Essayez l'insertion sur la table
2. Si 1 échoue, supprimez la ligne et insérez une nouvelle ligne

L'insertion sur la mise à jour de clé en double implique:
1.Essayez l'insert sur la table
2.Si 1 échoue, mettre à jour la ligne

Si toutes les étapes impliquées sont des insertions, il ne devrait pas y avoir de différence de performances. La vitesse doit dépendre du nombre de mises à jour impliquées. Le pire des cas est lorsque toutes les déclarations sont des mises à jour

J'ai essayé les deux déclarations sur ma table InnoDB impliquant 62 510 entrées (uniquement les mises à jour). Sur les vitesses de camping:
Remplacer en: 77,411 secondes
Insertion sur la mise à jour de la clé en double: 2,446 secondes

Insert on Duplicate Key update is almost 32 times faster.

Taille du tableau: 1 249 250 lignes avec 12 colonnes sur un Amazon m3.medium

39
katrix

Lorsque vous utilisez REPLACE au lieu de INSERT ... ON DUPLICATE KEY UPDATE, J'observe parfois des problèmes de verrouillage ou d'interblocage de clés lorsque plusieurs requêtes arrivent rapidement pour une clé donnée. L'atomicité de ce dernier (en plus de ne pas provoquer de suppressions en cascade) est une raison de plus pour l'utiliser.

8
Andrew Mao

Dans quels cas particuliers REMPLACER peut-il être préféré à INSÉRER ... SUR LA MISE À JOUR DE LA DUPLICATE KEY et vice versa?

Je viens de découvrir à la dure que dans le cas des tables avec un moteur de stockage FEDERATED INSERT...ON DUPLICATE KEY UPDATE les instructions sont acceptées, mais échouent (avec une erreur 1022: impossible d'écrire; clé en double dans le tableau ...) si une violation de clé en double se produit - voir la puce correspondante sur cette page de le manuel de référence MySQL.

Heureusement, j'ai pu utiliser REPLACE au lieu de INSERT...ON DUPLICATE KEY UPDATE dans mon déclencheur après insertion pour obtenir le résultat souhaité de la réplication des modifications dans une table FEDERATED.

3
w5m

Remplacer semble qu'il effectue deux opérations dans le cas où la clé existe déjà. Cela implique peut-être qu'il y a une différence de vitesse entre les deux?

(INSÉRER) une mise à jour vs une suppression + une insertion (REMPLACER)

EDIT: Mon implication que remplacer pourrait être plus lent est en fait complètement fausse. Eh bien, selon ce billet de blog de toute façon ... http://www.tokutek.com/2010/07/why-insert-on-duplicate-key-update-may-be-slow-by-incurring -disk-cherche /

2
Isaac Fife

"Il est possible que dans le cas d'une erreur de clé en double, un moteur de stockage puisse effectuer le REMPLACEMENT en tant que mise à jour plutôt que suppression plus insertion, mais la sémantique est la même."

http://dev.mysql.com/doc/refman/5.7/en/replace.html

1
user3522775

Si vous ne listez pas toutes les colonnes, je pense que REPLACE réinitialisera toutes les colonnes non mentionnées avec leurs valeurs par défaut dans les lignes remplacées. ON DUPLICATE KEY UPDATE laissera les colonnes non mentionnées inchangées.

1
Barmar