MYSQL开发性能研究——INSERT,REPLACE,INSERT-UPDATE性能比较

1、为何要有这个实验html

咱们的系统是批处理系统,相似于管道的架构。而各个数据表就是管道的两端,而咱们的程序就相似于管道自己。咱们所须要作的事情无非就是从A表抽取数据,通过必定过滤、汇总等操做放置到B表。若是出现了错误,那么就从从新跑这一个管道。因此说,咱们的系统其实根本就不要什么事务性,无非就是挂了把表给TRUNCATE(或者有条件地DELETE)一下,而后重跑就好了。mysql

这样一来,对于select语句就相对比较容易,基本上不须要作JOIN操做。然而对于写操做就有一些要求。好比说,须要处理主键重复(可能以前跑挂了,如今须要重跑,究竟是提示错误呢,仍是作个REPLACE或者UPDATE)等等问题。sql

在引入了MYSQL以后,咱们发现MYSQL在SQL语句层面就提供了对于相似问题的解决。包括了INSERT,REPLACE,INSERT-ON-DUPLICATE的操做。具体的说明请查看这里。惟一须要注意的是INSERT-ON-DUPLICATE这个操做,在UPDATE里面的VALUES的含义是INSERT列表里的那个固定值,若是须要引用数据表中原来的值,仍是直接使用列名便可,无需用VALUES包装一下。数据库

 

 

2、实验准备多线程

我仍然是采用了在咱们这里可能用到的最大的表,该表有近200个字段。实验环境也和上一篇文章中的同样。有了那篇文章中的比较,我就直接使用了10条多行插入的方法,也是每5000条提交一次。为了作个比较,我特地制做了一个传统的INSERT-UPDATE操做。该操做先进行INSERT插入动做,而后检查输出,若是是出现了“主键重复”的错误,那么直接调用UPDATE语句,用相同的数据替换那行(就是直接原值覆盖)。注意,这种办法是没有办法作到多行插入的。架构

一样,为了让场景更加真实。我在同一个MYSQL服务上建立了三个数据库,其中都建立了该表。并且全部的操做都直接针对该三张表进行。我在代码里使用的工具是我本身写的一个类库。经过多线程链接到多库(一库一链接)而后主线程向全部线程发送一句INSERT/REPLACE/INSERT-UPDATE/INSERT-ON-DUPLICATE-KEY命令,等待全部线程都返回继续向下。全部的COMMIT操做都是线程主动根据AFFECTED ROWS的累积量本身选择作。工具

再强调一下,机器很烂,TPS没有意义。只是看个趋势。
性能

 

3、实验结果.net

说明:线程

  • 多行INSERT空表——使用”INSERT INTO … VALUES (..), (..), (..), … “的方式往一张空表里面插入数据。
  • INSERT-UPDATE——在上一步骤的基础上,该操做先进行INSERT插入动做(一条一条INSERT),而后检查错误输出,若是是出现了“主键重复”的错误,那么直接调用UPDATE语句,用相同的数据替换那行(就是直接原值覆盖)。
  • 多行REPLACE空表——使用“REPLACE INSERT INTO … VALUES (..), (..), (..), … ”的方式往一张空表里面插入数据。
  • INSERT-DUPLICATE——使用 INSERT INTO .. VALUES (..), (..), (..), … ON DUPLICATE KEY UPDATE …”的语法在上一步骤的基础上进行操做。

image

 

结论以下:

  • 对于空表操做,REPLACE的性能和INSERT的差很少,可是他还有一个额外的好处,就是能够进行覆盖操做。这就给了咱们一点提示,若是咱们真的不用去关心DUPLICATE KEY错误,并且但愿作到覆盖效果,那么使用REPLACE真心不错;若是不用关心DUPLICATE KEY错误,同时也不想要覆盖,那么INSERT IGNORE更好。
  • 传统的INSERT-UPDATE方式真心慢,理解起来也不复杂,送过去-返回来-再送过去-再返回来。仍是改用INSERT-ON-DUPLICATE-KEY-UPDATE吧。
相关文章
相关标签/搜索