关于批量插入数据之我见(100万级别的数据,mysql)

因前段时间去面试,问到如何高效向数据库插入10万条记录,之前没处理过类似问题,也没看过相关资料,结果没答上来,今天就查了些资料,总结出三种方法:

测试数据库为mysql!!!

方法一:

public static void insert() {
		// 开时时间
		Long begin = new Date().getTime();
		// sql前缀
		String prefix = "INSERT INTO tb_big_data (count, create_time, random) VALUES ";
		try {
			// 保存sql后缀
			StringBuffer suffix = new StringBuffer();
			// 设置事务为非自动提交
			conn.setAutoCommit(false);
			// Statement st = conn.createStatement();
			// 比起st,pst会更好些
			PreparedStatement pst = conn.prepareStatement("");
			// 外层循环,总提交事务次数
			for (int i = 1; i <= 100; i++) {
				// 第次提交步长
				for (int j = 1; j <= 10000; j++) {
					// 构建sql后缀
					suffix.append("(" + j * i + ", SYSDATE(), " + i * j
							* Math.random() + "),");
				}
				// 构建完整sql
				String sql = prefix + suffix.substring(0, suffix.length() - 1);
				// 添加执行sql
				pst.addBatch(sql);
				// 执行操作
				pst.executeBatch();
				// 提交事务
				conn.commit();
				// 清空上一次添加的数据
				suffix = new StringBuffer();
			}
			// 头等连接
			pst.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		// 结束时间
		Long end = new Date().getTime();
		// 耗时
		System.out.println("cast : " + (end - begin) / 1000 + " ms");
	}

输出时间:cast : 23 ms

该方法目前测试是效率最高的方法!

方法二:

public static void insertRelease() {
		Long begin = new Date().getTime();
		String sql = "INSERT INTO tb_big_data (count, create_time, random) VALUES (?, SYSDATE(), ?)";
		try {
			conn.setAutoCommit(false);
			PreparedStatement pst = conn.prepareStatement(sql);
			for (int i = 1; i <= 100; i++) {
				for (int k = 1; k <= 10000; k++) {
					pst.setLong(1, k * i);
					pst.setLong(2, k * i);
					pst.addBatch();
				}
				pst.executeBatch();
				conn.commit();
			}
			pst.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		Long end = new Date().getTime();
		System.out.println("cast : " + (end - begin) / 1000 + " ms");
	}

注:注释就没有了,和上面类同,下面会有分析!

控制台输出:cast : 111 ms

执行时间是上面方法的5倍!

方法三:

public static void insertBigData(SpringBatchHandler sbh) {
		Long begin = new Date().getTime();
		JdbcTemplate jdbcTemplate = sbh.getJdbcTemplate();
		final int count = 10000;
		String sql = "INSERT INTO tb_big_data (count, create_time, random) VALUES (?, SYSDATE(), ?)";
		jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
			// 为prepared statement设置参数。这个方法将在整个过程中被调用的次数
			public void setValues(PreparedStatement pst, int i)
					throws SQLException {
				pst.setLong(1, i);
				pst.setInt(2, i);
			}

			// 返回更新的结果集条数
			public int getBatchSize() {
				return count;
			}
		});
		Long end = new Date().getTime();
		System.out.println("cast : " + (end - begin) / 1000 + " ms");
	}

该方法采用的是spring batchUpdate执行,因效率问题,数据量只有1万条!

执行时间:cast : 387 ms

总结:方法一和方法二很类同,唯一不同的是方法一采用的是“insert into tb (...) values(...),(...)...;”的方式执行插入操作,

方法二则是“insert into tb (...) values (...);insert into tb (...) values (...);...”的方式,要不是测试,我也不知道两者差别是如此之大!

当然,这个只是目前的测试,具体执行时间和步长也有很大关系!如过把步长改为100,可能方法就要几分钟了吧,这个可以自己测试哈。。。

方法三网上很推崇,不过,效率大家也都看到了,1万条记录,耗时6分钟,可见其效率并不理想!而且方法三需要配置spring applicationContext环境才能应用!

不过,方法三在ssh/spring-mvc中可用性还是很高的!

刚才开始研究大数据方面的问题,以上也只是真实测试的结果,并不一定就是事实,有好的建议,大家请指正,谢谢!

相互学习,才能进步更快!

晚点会把源码发上来,大家可以直接去下载测试!

时间: 2024-10-28 08:48:40

关于批量插入数据之我见(100万级别的数据,mysql)的相关文章

菁优网(jyeoo.com)题库数据(题目数据超102万组题数据超2100万含图片)

本文原创作者:数据超市(http://www.data-shop.net) 本文原始链接:http://www.data-shop.net/2016/03/jyeoo_com_20160321/ 数据说明:菁优网(http://www.jyeoo.com/)的题库数据.是按网站上的学科.教材组题来采集的,数据总数21,125,850条.数据包括以下学科:小学 – 数学初中 – 数学,物理,化学,生物,地理高中 – 数学,物理,化学,生物 特别说明:本次采集内容包括菁优网上初中.高中.小学的所有的

C#导出数据量大于100万【csv】

/// <summary> /// Export the data from datatable to CSV file /// </summary> /// <param name="grid"></param> public void ExportDataGridToCSV(System.Data.DataTable dt) { string strFile = ""; string path = "&q

极限挑战—C#+ODP 100万条数据导入Oracle数据库仅用不到1秒

链接地址:http://www.cnblogs.com/armyfai/p/4646213.html 要:在这里我们将看到的是C#中利用ODP实现在Oracle数据库中瞬间导入百万级数据,这对快速批量导入的实现有重要意义. .Net程序中可以通过ODP调用特性,对Oracle数据库进行操作,今天来讲一下数据批量插入的功能,所用技术不高不深,相信很多朋友都接触过,小弟班门弄斧了,呵呵.这篇文章是上篇文章的续集,因为上一次试验的征集结果没有突破4秒的方法,所以这次继续挑战与挖掘新方法,虽然是Orac

年薪50万的大数据分析师养成记【摘抄】

以下是一位在数据分析领域打滚了N年后,写下的一些体会,一定能给新人一些借鉴的地方.(总结的不错,大家可以借鉴学习哦) 一.数据分析师有哪些要求? 1.理论要求及对数字的敏感性,包括统计知识.市场研究.模型原理等. 2.工具使用,包括挖掘工具.数据库.常用办公软件(excel.PPT.word.脑图)等. 3.业务理解能力和对商业的敏感性.对商业及产品要有深刻的理解,因为数据分析的出发点就是要解决商业的问题,只有理解了商业问题,才能转换成数据分析的问题,从而满足部门的要求. 4.汇报和图表展现能力

mysql8.0如何快速生成100万数据人员信息数据

在爱学习mysql优化时 我需要大量数据才检测sql语句的效率 下面给大家模拟一个生成100万人员信息的数据的范例 创建一个数据库  名为test 建立表 create table t(id bigint not null auto_increment primary key, mobile bigint, password varchar(64), username varchar(64), sex tinyint not null default 1, birthday datetime,

各种数据库的批量插入操作_Oracle

最近工作中需要优化以前各种的Excel批量导入功能,目前将能优化的方面做个记录. 选用技术: 目前.Net可以访问Oracle常用的Dll,有三种: 微软自带的 System.Data.OracleClient Oracle 公司提供的 Oracle.DataAccess System.Data.OleDb  通过比对以后,使用第二种,其原因如下: 访问数据库方式 优点 缺点 System.Data.OracleClient 操作简单,无论32,64直接引用即可使用 微软在4.0之后不会对其更新

Mysql批量插入返回Id错乱(原因分析)

在项目中经常会有如下场景: 往数据库中批量插入一批数据后,需要知道哪些插入成功,哪些插入失败了. 这时候往往会有两种思路,一个是在插入之前判断相同的记录是否存在,过滤掉重复的数据:另外一种就是边插入边判断,动态过滤. 第一种方式对于数据量过大的情况并不适用,为了采用第二种方法,我们使用了"Mybatis批量插入返回自增主键"的方式进行处理. mysql插入操作后返回主键是jdbc的功能,用到的方法是getGeneratedKeys()方法,使用此方法获取自增数据,性能良好,只需要一次交

年薪50万的大数据分析师养成记

以下是一位在数据分析领域打滚了N年后的分析师写下的一些总结和体会大家可以借鉴学习! 一.成为数据分析师有哪些要求? 1.理论知识要宽泛,涉及数学.市场和技术.要求及对数据敏感,包括统计知识.市场研究.模型原理等. 2.常规分析工具的使用,包括数据库.数据挖掘.统计分析工具,常用办公软件(Excel.PPT.思维导图)等等. 3.有一定的业务理解能力,能理解业务背后的商业逻辑.因为只有理解了商业问题,才能转换成数据分析的问题,从而满足部门的要求. 4.数据报告和数据可视化的能力.数据分析得再好,如

批量插入100万条数据

创建数据库: --Create DataBase create database BulkTestDB; go use BulkTestDB; go --Create Table Create table BulkTestTable( Id int primary key, UserName nvarchar(32), Pwd varchar(16)) go --Create Table Valued CREATE TYPE BulkUdt AS TABLE (Id int, UserName