1.初始化表和测试数据

CREATE TABLE t1 SELECT 1 AS a, 'c3' AS b, 'c2' AS c;
ALTER TABLE t1 CHANGE a a INT PRIMARY KEY AUTO_INCREMENT ;
INSERT INTO t1 SELECT 2,'2', '3';
insert into t1(b,c) select 'r2','r3';

MySQL中Replace into语句与Insert into on duplicate key update语句对比_数据

 2.replace语句测试

replace into是insert into 的加强版,既可以更新数据也可以插入数据;

它的执行逻辑是:首先判断是否存在相同的唯一主键或者唯一索引,如果存在,则更新数据,否则,插入数据。例如:

[SQL]REPLACE INTO t1(a,b,c) VALUES(2,'22','22') ;
受影响的行: 2
时间: 0.048s

MySQL中Replace into语句与Insert into on duplicate key update语句对比_更新数据_02

之所以会是2行数据受到影响,是因为表中已存在主键为2的数据,mysql先将原有的数据删除,并将新的数据插入,因此受影响的是2行数据。

再看下面的例子:

[SQL]REPLACE INTO t1(a) VALUES(3) ;
受影响的行: 2
时间: 0.039s

MySQL中Replace into语句与Insert into on duplicate key update语句对比_数据_03

可以看出,确实是先删除后插入,当主键存在时,replace覆盖相关字段,其它字段填充默认值,可以理解为删除重复key的记录,新插入一条记录,一个delete原有记录再insert的操作

insert into  on duplicate key udpate 和replace into 类似,也是可以插入和更新,它们的不同点是,insert .. on deplicate udpate保留了所有字段的旧值,再覆盖然后一起insert进去,而replace没有保留旧值,直接删除再insert新值。从底层执行效率上来讲,replace要比insert .. on deplicate update效率要高,但是在写replace的时候,字段要写全,防止老的字段数据被删除。

关于insert on update的详细用法和说明可以看我其他两篇文章:

Mysql死锁排查:insert on duplicate死锁一次排查分析过程

Mybatis大量数据的插入或更新操作方案思考(使用ON DUPLICATE KEY UPDATE)

3.总结

如果存在相同的主键或唯一索引,replace into 相当于先删除数据而后在插入,如果不存在相同的主键和唯一索引,则直接插入。

如果存在相同的主键或唯一索引,insert into  on duplicate key update只更新update后面的字段,相当于udpate ;如果不存在相同的主键或唯一索引,则直接插入。