MySQL中的`REPLACE`和`INSERT … ON DUPLICATE KEY UPDATE`之间的实际区别是什么?

我需要的是用一个特定的键设置logging的所有字段的值(键实际上是复合键),插入logging如果没有这样的logging的logging呢。

REPLACE似乎是为了完成这项工作,但同时它的手册页build议INSERT ... ON DUPLICATE KEY UPDATE

我应该更好地select什么?为什么?

我想到的唯一的“副作用” REPLACE是,它会增加自动增量值(幸运的是,我不使用任何),而INSERT ... ON DUPLICATE KEY UPDATE可能不会。 还有什么其他的实际差异需要考虑? 在哪些情况下,可以将REPLACE优先于INSERT ... ON DUPLICATE KEY UPDATE ,反之亦然?

REPLACE内部执行删除操作,然后执行插入操作。 这可能会导致问题,如果您有一个外键约束指向该行。 在这种情况下, REPLACE可能会失败或者更糟:如果您的外键被设置为级联删除, REPLACE将导致其他表中的行被删除。 即使在REPLACE操作之前和之后都满足约束条件,也会发生这种情况。

使用INSERT ... ON DUPLICATE KEY UPDATE避免了这个问题,因此是首选。

为了回答这个问题,我使用了这两种方法做了testing

replace涉及:
1.尝试在桌子上插入
2.如果1失败,则删除行并插入新行

在重复密钥更新上插入涉及:
1.尝试在桌上插入
2.如果1失败,更新行

如果涉及的所有步骤都是插入的,那么性能应该没有什么不同。 速度取决于涉及的更新数量。 最糟糕的情况是所有的陈述都是更新的

我已经尝试了两个涉及62,510个条目(仅更新)的InnoDB表上的语句。 在速度上:
replace成:77.411秒
插入重复密钥更新:2.446秒

 Insert on Duplicate Key update is almost 32 times faster. 

表大小:亚马逊m3.medium上有1,249,250行12列

当使用REPLACE而不是INSERT ... ON DUPLICATE KEY UPDATE ,有时会在多个查询快速到达给定键时观察到键locking或死锁问题。 后者的primefaces性(除了不导致级联删除之外)更是使用它的原因。

在哪些情况下,可以将REPLACE优先于INSERT … ON DUPLICATE KEY UPDATE,反之亦然?

我刚刚发现硬的方式,在表格的情况下,与FEDERATED存储引擎INSERT...ON DUPLICATE KEY UPDATE语句被接受,但失败(错误1022:无法写入;重复键在表中。 ..)如果发生重复键违例 – 请参阅MySQL参考手册本页面上的相应项目符号。

幸运的是,我可以在插入后触发器中使用REPLACE而不是INSERT...ON DUPLICATE KEY UPDATE来实现将更改复制到FEDERATED表的所需结果。

replace似乎它在键已经存在的情况下执行两个操作。 也许这意味着两者之间存在速度差异?

(INSERT)一个更新与一个删除+一个插入(REPLACE)

编辑:我的意思是,replace可能会更慢,实际上是完全错误的。 那么,无论如何,根据这个博客文章… http://www.tokutek.com/2010/07/why-insert-on-duplicate-key-update-may-be-slow-by-incurring-disk-seeks /

如果您没有列出所有列,我认为REPLACE将会使用它们在replace行中的默认值重置任何未提及的列。 ON DUPLICATE KEY UPDATE会留下未提及的列。

“有可能在存在重复键错误的情况下,存储引擎可能会执行REPLACE作为更新而不是删除加插入,但是语义是相同的。

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