[转发]

导读

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

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

直接

直接每条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操作中也给了一种方式,语法如下:

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性能了,这也会导致数据的更新速度慢。

实例:

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

原文链接:http://segmentfault.com/a/1190000002527333

MySQL 避免重复数据的批量插入与批量更新的更多相关文章

  1. SQL server 存储过程 C#调用Windows CMD命令并返回输出结果 Mysql删除重复数据保留最小的id C# 取字符串中间文本 取字符串左边 取字符串右边 C# JSON格式数据高级用法

    create proc insertLog@Title nvarchar(50),@Contents nvarchar(max),@UserId int,@CreateTime datetimeasi ...

  2. 三十、MySQL 处理重复数据

    MySQL 处理重复数据 有些 MySQL 数据表中可能存在重复的记录,有些情况我们允许重复数据的存在,但有时候我们也需要删除这些重复的数据. 本章节我们将为大家介绍如何防止数据表出现重复数据及如何删 ...

  3. DB-MySQL:MySQL 处理重复数据

    ylbtech-DB-MySQL:MySQL 处理重复数据 1.返回顶部 1. MySQL 处理重复数据 有些 MySQL 数据表中可能存在重复的记录,有些情况我们允许重复数据的存在,但有时候我们也需 ...

  4. mybatis+mysql批量插入和批量更新、存在及更新

    mybatis+mysql批量插入和批量更新 一.批量插入 批量插入数据使用的sql语句是: insert into table (字段一,字段二,字段三) values(xx,xx,xx),(oo, ...

  5. mysql删除重复数据只保留一条

    mysql删除重复数据只保留一条 新建一张测试表: CREATE TABLE `book` ( `id` char(32) NOT NULL DEFAULT '', `name` varchar(10 ...

  6. MongoDB与传统数据库的使用区别——批量插入与批量查询

    我在百X知道上回答问题时经常遇到类似与这样的问题:MongoDB有没有像MySQL一样的ODBC驱动?MongoDB能不能像MySQL一样获取字段名称或类型. 我的回答是:不行,因为MongoDB不是 ...

  7. spring data jpa开启批量插入、批量更新

    spring data jpa开启批量插入.批量更新 原文链接:https://www.cnblogs.com/blog5277/p/10661096.html 原文作者:博客园--曲高终和寡 *** ...

  8. oracle 在xml中批量插入,批量修改及多组条件查询

    最近公司用ibatis开发项目,本来可以用存储过程处理批量插入,批量修改及多组条件查询:但由于使用模块相对较小,暂时就在xml中配置,以前没有在xml做过类似处理,有必要记录一下:好了,代码如下: & ...

  9. MySQL 查询重复数据,删除重复数据保留id最小的一条作为唯一数据

    开发背景: 最近在做一个批量数据导入到MySQL数据库的功能,从批量导入就可以知道,这样的数据在插入数据库之前是不会进行重复判断的,因此只有在全部数据导入进去以后在执行一条语句进行删除,保证数据唯一性 ...

随机推荐

  1. Handsontable的前端分页与数据库分页

    Handsontable虽然处理速度很快,但当数据量达到10W+的时候很容易导致浏览器内存泄漏,这时候可以用分页来解决.官网提供了前端分页demo,测试后发现也只能处理低于10W的数据,而且调试的时候 ...

  2. docker 使用案例:部署nginx

    首先安装docker.可以参考这篇教程: http://www.runoob.com/docker/windows-docker-install.html 本教程以windows10+ubuntu:1 ...

  3. asp.net core 五 SignalR 负载均衡

           SignalR : Web中的实时功能实现,所谓实时功能,就是所连接的客户端变的可用时,服务端能实时的推送内容到客户端,而不是被动的等待客户端的请求.Asp.net SignalR 源码 ...

  4. Spring Boot 2.0(四):使用 Docker 部署 Spring Boot

    Docker 技术发展为微服务落地提供了更加便利的环境,使用 Docker 部署 Spring Boot 其实非常简单,这篇文章我们就来简单学习下. 首先构建一个简单的 Spring Boot 项目, ...

  5. form + iframe 获取表单提交后返回的数据

    原理: submit 提交表单没有回调函数,但是可以用iframe来接收返回结果,最后进行格式转换就ok了: 原文地址: http://blog.csdn.net/simeng_1016/articl ...

  6. find命令总结

    find命令 2018-2-27日整理完成 1,结合-exec的用法 查当前目录下的所有普通文件,并在 -exec 选项中使用ls -l命令将它们列出# find . -type f -exec ls ...

  7. Linux设备驱动故障定位指引与实例

    Linux设备驱动故障定位指引 Linux设备驱动种类繁多,涉及的知识点多,想写一个通用的故障定位方法指引,是个难度颇大且不容易做好的工作.限于笔者的经验,难以避免存在疏漏之处,欢迎大家留言指正补充. ...

  8. 写了个批量查询qs的软件

    因为需要,自己写了个批量查询qs的小软件.从网站中抓出需要的数据,格式化显示: 对字符串进行检测处理,先用Replace函数去掉字符串的空格,再用正则表达式匹配,返回匹配的字符串,如果没有匹配,则返回 ...

  9. JavaScript -- 知识点汇总

    js语法 1. javascript数据类型 JavaScript拥有动态类型.这意味着相同的变量可用作不同的类型:有 字符串,数字, 布尔值, 对象, 数组,Undefined和Null 对象: v ...

  10. 利用Java生成UUID

    UUID是什么? UUID 是 通用唯一识别码(Universally Unique Identifier)的缩写,是一种软件建构的标准,亦为开放软件基金会组织在分布式计算环境领域的一部分.其目的,是 ...