Lo que necesito es establecer los valores de todos los campos de un registro con una clave en particular (la clave es compuesta en realidad), insertando el registro si todavía no hay ningún registro con dicha clave.
REPLACEparece destinado a hacer el trabajo, pero al mismo tiempo sugiere su página de manual
INSERT ... ON DUPLICATE KEY UPDATE.
¿Cuáles de ellos debería elegir mejor y por qué?
El único "efecto secundario" de REPLACEeso que me viene a la mente es que incrementaría los valores de autoincremento (afortunadamente no uso ninguno) mientras que INSERT ... ON DUPLICATE KEY UPDATEprobablemente no lo haría. ¿Cuáles son las otras diferencias prácticas a tener en cuenta? ¿En qué casos particulares se REPLACEpuede preferir INSERT ... ON DUPLICATE KEY UPDATEy viceversa?

Respuestas:
REPLACEinternamente realiza una eliminación y luego una inserción. Esto puede causar problemas si tiene una restricción de clave externa que apunta a esa fila. En esta situación,REPLACEpodría fallar o peor: si su clave externa está configurada para eliminar en cascada,REPLACEhará que las filas de otras tablas se eliminen. Esto puede suceder incluso si la restricción se cumplió tanto antes como después de laREPLACEoperación.El uso
INSERT ... ON DUPLICATE KEY UPDATEevita este problema y, por lo tanto, es preferible.fuente
INSERT ... ON DUPLICATE KEY UPDATEparece considerablemente "mejor", ¿en qué casos particulares puede "REEMPLAZAR" ser una mejor opción?REPLACEactualizará su valor de incremento automático de PK si hace unDELETEyINSERT. Que es exactamente lo que quiero. No quiero que el consumidor encuentre el registro bajo el mismo PK, por lo que no obtiene filas. Cuando quiero que lo encuentren (actualización real), usoUPDATEREPLACEmásINSERT ... ON DUPLICATE KEY UPDATE? ¿Por qué se preferiría unINSERT+DELETEsobre unUPDATE?Para responder a la pregunta en términos de rendimiento, hice una prueba usando ambos métodos
Reemplazar en implica:
1. Intente insertar en la tabla
2. Si 1 falla, elimine la fila e inserte una nueva fila
Insertar en clave duplicada La actualización implica:
1.Intentar insertar en la tabla
2.Si 1 falla, actualizar fila
Si todos los pasos involucrados son insertos, no debería haber diferencia en el rendimiento. La velocidad tiene que depender del número de actualizaciones involucradas. El peor de los casos es cuando todas las declaraciones son actualizaciones.
Probé ambas declaraciones en mi tabla InnoDB que involucran 62,510 entradas (solo actualizaciones). En velocidades de campaña:
Reemplazar en: 77.411 segundos
Insertar en clave duplicada Actualización: 2.446 segundos
Insert on Duplicate Key update is almost 32 times faster.Tamaño de la tabla: 1.249.250 filas con 12 columnas en un Amazon m3.
fuente
Insert on Duplicate Key Replace? ¿Fue más lento?ON DUPLICATE KEY UPDATE, no puedes escribirON DUPLICATE KEY REPLACE. Si desea actualizar todos los valores de la fila existente al duplicar la clave, debe escribirON DUPLICATE KEY UPDATE col1=VALUES(col1), col2=VALUES(col2), ...: debe enumerar todas las columnas manualmente.Cuando utilizo en
REPLACElugar deINSERT ... ON DUPLICATE KEY UPDATE, a veces observo problemas de bloqueo o interbloqueo de teclas cuando llegan varias consultas rápidamente para una clave determinada. La atomicidad de este último (además de no causar eliminaciones en cascada) es una razón de más para usarlo.fuente
Si no enumera todas las columnas, creo
REPLACEque restablecerá las columnas no mencionadas con sus valores predeterminados en las filas reemplazadas.ON DUPLICATE KEY UPDATEdejará las columnas no mencionadas sin cambios.fuente
Acabo de descubrir por las malas que, en el caso de tablas con un motor de almacenamiento FEDERADO, las
INSERT...ON DUPLICATE KEY UPDATEdeclaraciones se aceptan, pero fallan (con un Error 1022: No se puede escribir; clave duplicada en la tabla ...) si hay una clave duplicada se produce una infracción: consulte el punto correspondiente en esta página del Manual de referencia de MySQL.Afortunadamente, pude usar en
REPLACElugar deINSERT...ON DUPLICATE KEY UPDATEdentro de mi activador de inserción posterior para lograr el resultado deseado de replicar los cambios en una tabla FEDERADA.fuente
Reemplazar parece que hace dos operaciones en el caso de que la clave ya exista. ¿Quizás eso implica que hay una diferencia de velocidad entre los dos?
(INSERTAR) una actualización frente a una eliminación + una inserción (REEMPLAZAR)
EDITAR: Mi implicación de que el reemplazo podría ser más lento es en realidad completamente incorrecta. Bueno, de acuerdo con esta publicación de blog de todos modos ... http://www.tokutek.com/2010/07/why-insert-on-duplicate-key-update-may-be-slow-by-incurring-disk-seeks /
fuente
"Es posible que en el caso de un error de clave duplicada, un motor de almacenamiento pueda realizar REPLACE como una actualización en lugar de eliminar más insertar, pero la semántica es la misma".
http://dev.mysql.com/doc/refman/5.7/en/replace.html
fuente
REPLACE parece ser necesario a veces porque INSERT IGNORE no parece funcionar con transformaciones de datos.
Si hago esto, solo configuro largerCityPop a sí mismo:
Si hago esto, estoy usando la función GRUPO incorrectamente:
Y si hago esto, MySQL no reconocerá el nombre de la columna:
Esto funciona, pero parece simplemente feo:
fuente
INSERT IGNOREconsulta finalizará correctamente (y emitirá una advertencia) si falla una restricción externa . Si desea detectar un error como este, mejor useON DUPLICATE KEY UPDATEsinIGNORE.