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?
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.
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
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.
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.
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 /
"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."
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.