mysql批量插入 增加参数_MySql 的批量操作,要加rewriteBatchedStatements参数

MySql 的批量操作,要加rewriteBatchedStatements参数

作者:赵磊

博客:http://elf8848.iteye.com

--------------------------------结论 ---------------------------------

MySql   非批量 10万条记录,                 5700条/秒

MySql   批量(batch) 10万条记录,         62500条/秒

oracle   非批量插入10万条记录,            4464 条/秒

oracle   批量 (batch)插入10万条记录,   27778 条/秒

注:以上测试都是在插入10万条数据完成之后,一次性提交事务(对性能影响很大,占了很大便宜)。

另有一篇文章,说明提交事务的次数对insert性能的影响:《MySql 插入(insert)性能测试 》

MySql的JDBC连接的url中要加rewriteBatchedStatements参数,并保证5.1.13以上版本的驱动,才能实现高性能的批量插入。

例如: String connectionUrl="jdbc:mysql://192.168.1.100:3306/test?rewriteBatchedStatements=true";

还要保证Mysql JDBC驱的版本。MySql的JDBC驱动的批量插入操作性能是很优秀的。

Mysql JDBC驱动,各个版本测试结果:

MySql JDBC 驱动版本号

插入10万条数据用时

5.0.8

加了rewriteBatchedStatements参数,没有提高还是17.4秒

5.1.7

加了rewriteBatchedStatements参数,没有提高还是17.4秒

5.1.13

加了rewriteBatchedStatements参数,插入速度提高到1.6秒

关于rewriteBatchedStatements参数,Mysql官方的说明:

Should the driver use multiqueries (irregardless of the setting of "allowMultiQueries") as well as rewriting of prepared statements for INSERT into multi-value inserts when executeBatch() is called? Notice that this has the potential for SQL injection if using plain java.sql.Statements and your code doesn't sanitize input correctly. Notice that for prepared statements, server-side prepared statements can not currently take advantage of this rewrite option, and that if you don't specify stream lengths when using PreparedStatement.set*Stream(), the driver won't be able to determine the optimum number of parameters per batch and you might receive an error from the driver that the resultant packet is too large. Statement.getGeneratedKeys() for these rewritten statements only works when the entire batch includes INSERT statements.

-------------------------事情的起因---------------------------------

原贴是《使用DBCP 数据库连接池遇到的两个比较怀疑的问题》http://www.iteye.com/topic/768416

帖子是问连接池问题的,主要是使用连接池向MySql插入大量数据的事儿,有很多javaEye的朋友让作者使用JDBC的批量操作来提高大量插入数据的性能。

mercyblitz 写道

elf8848 写道

前面有多位朋友提出,让楼主使用 jdbc的批量操作,就是PreparedStatement 类上的addBatch(),executeBatch()方法。

在这里要提醒一下大家,MySql的JDBC驱动,是不支持批量操作的,就算你在代码中调用了批量操作的方法,MySql的JDBC驱动,也是按一般insert操作来处理的。

同样Fetch Size特性MySql的JDBC驱动也不支持。而Oracle的JDBC驱动是都支持的。

楼主使用的是Mysql数据库, 不要指望通过批处理来提高 性能了。

请不要想当然,建议你去看一下MySQL JDBC的源代码!

MySQL JDBC驱动在发送命令是,都是传递一个数组的String类型,然后转化为一个二维byte数组。

如果是一条的Statement的话,这个String数组只有一个元素,如果是Batch的话,则有相应个元素。

最后发送IO命令。不清楚你的结论是哪里来的?

我在这里重复的提醒大家:

MySql的JDBC驱动,不是真正支持批量操作的,就算你在代码中调用了批量操作的方法,MySql的JDBC驱动也是按照一般操作来处理的。

这不是什么重大发现,也不是什么新消息,是老调重弹,如果你使用Mysql数据库不要寄希望于通过JDBC批量操作来提高大量插入数据的性能,起码目前的MySql的JDBC驱动是这样的。

--------------------------------- 测试环境 ---------------------------------

测试机:笔记本电脑ThinkPad T400

操作系统:Windows XP

CPU:P8600 2.4G

内存:2G

IP:192.168.10.124

数据库服务器:笔记本ThinkPad T400

操作系统:虚拟机Windows 2003

内存:操作系统分配了500M (真可怜啊)

IP:192.168.10.139

数据库服务器上安装有MySql5.0.18 ,Oracle10G,都是默认安装。

JDBC驱动版本:

MySql : mysql-connector-java-5.0.8

Oracle : ojdbc6.jar  (之前使用ojdbc14.jar批量插入10万条,实际只插入了3万多条,其它的丢失了,换ojdbc6.jar后,一次commit插入100万条也没有问题)

表只有两个字段:

id int

uname varchar(10)

innoDB引擎

---------------------------------测试结果: ---------------------------------

mysql非批量插入10万条记录

mysql批量插入10万条记录

(JDBC的URL中未加参数)

oracle非批量插入10万条记录

oracle批量插入10万条记录

第1次

17437 ms

17437 ms

22391 ms

360 ms

第2次

17422 ms

17562 ms

22297 ms

328 ms

第3次

17046 ms

17140 ms

22703 ms

359 ms

这里通过一个点也可以看出来Mysql批量与非批量性能是一样。

oracle的JDBC实现的批量操作的性能十分优秀。

---------------------------------测试方法: ---------------------------------

下面是测试代码:

Java代码  08961b1bb924ff051ad41a4e25950c72.png

package jdbc2;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.SQLException;

public class Mysql {

public static void main(String[] args) {

test_mysql();

//test_mysql_batch();

//test_oracle();

//test_oracle_batch();

}

/**

* mysql非批量插入10万条记录

* 第1次:17437 ms

* 第2次:17422 ms

* 第3次:17046 ms

*/

public static void test_mysql(){

String url="jdbc:mysql://192.168.10.139:3306/test";

String userName="root";

String password="1234";

Connection conn=null;

try {

Class.forName("com.mysql.jdbc.Driver");

conn =  DriverManager.getConnection(url, userName, password);

conn.setAutoCommit(false);

String sql = "insert into t_user(id,uname) values(?,?)";

PreparedStatement prest = conn.prepareStatement(sql);

long a=System.currentTimeMillis();

for(int x = 0; x 

prest.setInt(1, x);

prest.setString(2, "张三");

prest.execute();

}

conn.commit();

long b=System.currentTimeMillis();

System.out.println("MySql非批量插入10万条记录用时"+ (b-a)+" ms");

} catch (Exception ex) {

ex.printStackTrace();

}finally{

try {

if(conn!=null)conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

/**

* mysql批量插入10万条记录(未加rewriteBatchedStatements参数)   ,加了参数后是1600ms左右

* 第1次:17437 ms

* 第2次:17562 ms

* 第3次:17140 ms

*/

public static void test_mysql_batch(){

//String url="jdbc:mysql://192.168.10.139:3306/test";

     String url="jdbc:mysql://127.0.0.1:3306/dev?rewriteBatchedStatements=true";

String userName="root";

String password="1234";

Connection conn=null;

try {

Class.forName("com.mysql.jdbc.Driver");

conn =  DriverManager.getConnection(url, userName, password);

conn.setAutoCommit(false);

String sql = "insert into t_user(id,uname) values(?,?)";

PreparedStatement prest = conn.prepareStatement(sql);

long a=System.currentTimeMillis();

for(int x = 0; x 

prest.setInt(1, x);

prest.setString(2, "张三");

prest.addBatch();

}

prest.executeBatch();

conn.commit();

long b=System.currentTimeMillis();

System.out.println("MySql批量插入10万条记录用时"+ (b-a)+" ms");

} catch (Exception ex) {

ex.printStackTrace();

}finally{

try {

if(conn!=null)conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

/**

* oracle非批量插入10万条记录

* 第1次:22391 ms

* 第2次:22297 ms

* 第3次:22703 ms

*/

public static void test_oracle(){

String url="jdbc:oracle:thin:@192.168.10.139:1521:orcl";

String userName="scott";

String password="tiger";

Connection conn=null;

try {

Class.forName("oracle.jdbc.OracleDriver");

conn =  DriverManager.getConnection(url, userName, password);

conn.setAutoCommit(false);

String sql = "insert into t_user(id,uname) values(?,?)";

PreparedStatement prest = conn.prepareStatement(sql);

long a=System.currentTimeMillis();

for(int x = 0; x 

prest.setInt(1, x);

prest.setString(2, "张三");

prest.execute();

}

conn.commit();

long b=System.currentTimeMillis();

System.out.println("Oracle非批量插入10万记录用时"+ (b-a)+" ms");

conn.close();

} catch (Exception ex) {

ex.printStackTrace();

}finally{

try {

if(conn!=null)conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

/**

* oracle批量插入10万条记录

* 第1次:360 ms

* 第2次:328 ms

* 第3次:359 ms

*/

public static void test_oracle_batch(){

String url="jdbc:oracle:thin:@192.168.10.139:1521:orcl";

String userName="scott";

String password="tiger";

Connection conn=null;

try {

Class.forName("oracle.jdbc.OracleDriver");

conn =  DriverManager.getConnection(url, userName, password);

conn.setAutoCommit(false);

String sql = "insert into t_user(id,uname) values(?,?)";

PreparedStatement prest = conn.prepareStatement(sql);

long a=System.currentTimeMillis();

for(int x = 0; x 

prest.setInt(1, x);

prest.setString(2, "张三");

prest.addBatch();

}

prest.executeBatch();

conn.commit();

long b=System.currentTimeMillis();

System.out.println("Oracle批量插入10万记录用时"+ (b-a)+" ms");

conn.close();

} catch (Exception ex) {

ex.printStackTrace();

}finally{

try {

if(conn!=null)conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/514197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为开发者而生 | 2021 SuperMap开发者大会议程全公布

如果地理信息产业是一片江湖 SuperMap开发者大会 则是一场卧虎藏龙的群英会 技术卓越的大侠们在此一展风采 精通各路应用的绝世门派在此切磋技艺 一起修炼顶级武功秘籍 致敬技术极客精神 为开发者而生(D4D) 9月15日-18日 2021 SuperMap开发者大会…

Flink 如何实时分析 Iceberg 数据湖的 CDC 数据

简介: 数据湖的架构中,CDC 数据实时读写的方案和原理 本文由李劲松、胡争分享,社区志愿者杨伟海、李培殿整理。主要介绍在数据湖的架构中,CDC 数据实时读写的方案和原理。文章主要分为 4 个部分内容: 常见的 CDC 分析…

mysql 加载数据校验_mysql 导入数据后的校验程序

参考mysql导入样本数据库employees之后的数据校验,可以使用md5或者sha,原理与思路:首先在将要备份的数据库中生成每个表里的每行每列数据的累加计算md5值,接着hardcode在测试单元文件中,作为期望值。以下是md5的校验方…

如何通过事务消息保障抢购业务的分布式一致性?

简介: 在柔性事务的多种实现中,事务消息是最为优雅易用的一种。基于阿里云RocketMQ高性能、高可用的特点,完全可以胜任抢购业务这类高并发大流量的场景。但引入事务消息机制在实现高性能的同时,也增加了整体的业务复杂度。我们需要…

海量秋招面试资料等你来拿!你离大厂也许并不远

秋招在即,你还在为秋招如何准备而发愁吗?你还在为拿不到大厂offer而苦恼吗?工欲善其事,必先利其器。金秋开学季,CSDN助力你的技术学习与成长,为你免费提供海量大厂面试资料,让你的秋招不再慌乱&…

基于Ganos百行代码实现亿级矢量空间数据在线可视化

简介: 本文介绍如何使用RDS PG或PolarDB(兼容PG版或Oracle版)的Ganos时空引擎提供的数据库快显技术,仅用百行代码实现亿级海量几何空间数据的在线快速显示和流畅地图交互,且无需关注切片存储和效率问题。 01 引言 如何…

mysql 防注入 php_PHP+mysql防止SQL注入的方法小结

本文实例讲述了PHPmysql防止SQL注入的方法。分享给大家供大家参考,具体如下:SQL注入例:脚本逻辑$sql "SELECT * FROM user WHERE userid $_GET[userid] ";案例1:SELECT * FROM t WHERE a LIKE %xxx% OR (IF(NOWSYSDAT…

流批一体生产应用!Bigo 实时计算平台建设实践

简介: 本文由 Bigo 计算平台负责人徐帅分享,主要介绍 Bigo 实时计算平台建设实践的介绍 本文由 Bigo 计算平台负责人徐帅分享,主要介绍 Bigo 实时计算平台建设实践的介绍。内容包括: Bigo 实时计算平台的发展历程特色与改进业务场…

一部手机是否能用 7 年?苹果、三星、Google:三年差不多!

整理 | 苏宓出品 | CSDN(ID:CSDNnews)一部手机如果可以流畅地使用 7 年,是种什么样的感觉:有人说,这对于 iPhone 而言,或许会很轻松做到,但也会给一些平价的 Android 手机制造商带来…

五福背后的 Web 3D 引擎 Oasis Engine 正式开源

简介: Oasis 从开源走向新的起点,用 3D 化的交互和表达让世界变得更美好。 相信大家已经体验了今年支付宝五福的活动,无论是今年的五福首页还是打年兽游戏都是由蚂蚁互动图形引擎(代号:Oasis Engine)驱动的…

mysql驱动profilesql_java连接mysql的驱动配置问题

想用java访问mysql数据库,下载了一个驱动,然后根据网上说的,配置了classpath,结果失败,原因是ClassNotFoundException,然后继续往上搜索,最后将该驱动放置到jdk\lib\ext目录下,...想…

我用 Python 自制成语接龙小游戏,刺激!

作者:小小明原文链接:https://blog.csdn.net/as604049322/article/details/118154687本文为读者投稿在 https://github.com/pwxcoo/chinese-xinhua 项目中可以下载到中华成语的语料库,该项目收录包括 14032 条歇后语,16142 个汉字…

基于SLS构建RDS审计合规监控

简介: 数据库是企业业务的数据核心,其安全方面的问题在传统环境中已经成为泄漏和被篡改的重要根源。因此,对数据库的操作行为尤其是全量 SQL 执行记录的审计日志,就显得尤为重要。 背景 数据库是企业业务的数据核心,其…

云效DevOps实践-如何基于云效实现测试自动化集成和分析

简介: 对于现代软件研发来说,持续、快速、高质量、低风险地交付需求特性,是业务对研发的主要诉求。而要做到这一点,除了要有良好的架构设计、卓越的工程能力,快速可靠的测试反馈也是其非常重要的一环,达到这…

spring 使用其他类protected方法_Java操作bean、属性、方法的使用工具类

在实际的项目开发中,反射操作类的实例、属性赋值、执行方法是常规的操作,虽然spring提供了比较完整的API来执行上述操作,不过在实际的应用中,spring的函数隐藏比较深,比较分散,小伙伴们可能懒得花时间去寻找…

2021年阿里云采购季大促主会场全攻略

在疫情的影响下,企业都在谋求各种转机,探寻各种转型之路,为助力企业复工复产低成本上云,日前阿里云开年采购季优惠活动于3月1日正式开启。 从主会场页面来看,活动分为三个阶段: 3月1日-3月16日&#xff1a…

应云而生,幽灵的威胁 - 云原生应用交付与运维的思考

简介: 过去的 2020 是充满不确定性的一年,但也是充满机遇的一年。突发的新冠疫情为全社会的数字化转型按下加速键。云计算已经不再是一种技术,而是成为支撑数字经济发展和业务创新的关键基础设施。在利用云计算重塑企业 IT 的过程中&#xff…

mysql5.5编译安装参数_mysql-5.5源码编译安装(附参数对照表)

1. 命令语法:重新编译时,需要清除旧的对象文件和缓存信息# make clean# rm -f CMakeCache.txt2.安装选项CMAKE_INSTALL_PREFIX值是安装的基本目录,其他cmake选项值是不包括前缀,是相对路径名,绝对路径包括 CMAKE_INSTALL_PREFIX路…

Mendix宣布推出低代码人工智能与机器学习功能

编辑 | 宋 慧 供稿 | Mendix 2021年9月9日,企业低代码应用开发厂商Mendix在低代码人员线上活动——Mendix World 2021大会上宣布,推出平台新增功能,为数字化经济加速交付高价值解决方案。新增功能包括事件驱动架构、针对创客和最终用户的AI领…

技术干货 | mPaaS 小程序高玩带你起飞:客户端预置小程序无视网络质量

简介: 弱网拉包无障碍,深度提升用户体验 传统的小程序技术容易受到网络环境影响,当网络质量不佳时可能导致拉取不到小程序包的情况。通过预置小程序,即可规避该问题。本文介绍了预置小程序的原理和预置小程序的实现过程。 什么是预…