Mysql replace 与 insert on duplicate效率分析

导读

咱们在向数据库里批量插入数据的时候,会遇到要将原有主键或者unique索引所在记录更新的状况,而若是没有主键或者unique索引冲突的时候,直接执行插入操做。mysql

这种状况下,有三种方式执行:sql

直接

直接每条select, 判断, 而后insert,毫无疑问,这是最笨的方法了,不断的查询判断,有主键或索引冲突,执行update,不然执行insert. 数据量稍微大一点这种方式就不行了。数据库

稍微高级一些的方式。性能

replace

这是mysql自身的一个语法,使用 replace 的时候。其语法为:大数据

replace into tablename (f1, f2, f3) values(vf1, vf2, vf3),(vvf1, vvf2, vvf3)

这中语法会自动查询主键或索引冲突,若有冲突,他会先删除原有的数据记录,而后执行插入新的数据。优化

insert on duplicate key.

这也是一种方式,mysql的insert操做中也给了一种方式,语法以下:code

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=c+1;

在insert时判断是否已有主键或索引重复,若是有,一句update后面的表达式执行更新,不然,执行插入。索引

第一种方式不说了,replace和insert on duplicate key这两种方式,哪中效率更高一些呢,毕竟,咱们的执行sql,追求的就是高效。事务

分析

在最终实践结果中,获得接过以下:
在数据库数据量不多的时候, 这两种方式都很快,不管是直接的插入仍是有冲突时的更新,都不错,但在数据库表的内容数量比较大(如百万级)的时候,两种方式就不太同样了,内存

首先是直接的插入操做,两种的插入效率都略低, 好比直接向表里插入1000条数据(百万级的表(innodb引擎)),两者都差很少须要5,6甚至十几秒。究其缘由,个人主机性能是一方面,但在向大数据表批量插入数据的时候,每次的插入都要维护索引的, 索引当然能够提升查询的效率,但在更新表尤为是大表的时候,索引就成了一个不得不考虑的问题了。

其次是更新表,这里的更新的时候是带主键值的(由于我是从另外一个表获取数据再插入,要求主键不能变) 一样直接更新1000条数据, replace的操做要比insert on duplicate的操做低太多太多, 当insert瞬间完成(感受)的时候,replace要7,8s, replace慢的缘由我是知道的,在更新数据的时候,要先删除旧的,而后插入新的,在这个过程当中,还要从新维护索引,因此速度慢,但为什么insert on duplicate的更新却那么快呢。 在向老大请教后,终于知道,insert on duplicate 的更新操做虽然也会更新数据,但其对主键的索引却不会有改变,也就是说,insert on duplicate 更新对主键索引没有影响.所以对索引的维护成本就低了一些(若是更新的字段不包括主键,那就要另说了)。

题外话:

在向数据量大的表里批量插入更新数据的时候,随着插入的数量愈来愈多,会致使愈来愈慢,这种状况下,由于咱们用的innodb表,能够开启事务, 每次批量执行一批数据更新后提交, 再从新开事务处理下批数据,这样会有效增长效率

还有说明一下: 当咱们执行数据库的插入和更新操做很慢的时候,不只仅是语句,主机性能也很重要, 好比内存和cpu, 若是是虚拟机要相应适当调整, 若是在各类优化了以后效率仍是很低, 但cpu和内存的占用却不高,那么就极可能是磁盘的IO性能了,这也会致使数据的更新速度慢。

PS: 数据库菜鸟一个, 所知有限, 若有纰漏, 还请指教

相关文章
相关标签/搜索