关于批量插入数据之我见(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中可用性还是很高的!


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

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


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

好的,下面是将5万条记录批量插入MySQL的三个简单步骤: 1. 构建插入语句:首先,你需要构建一个插入语句,用于将数据插入MySQL中。例如,如果你要将数据插入到名为“mytable”的表中,可以使用以下语句: ``` INSERT INTO mytable (column1, column2, column3, ...) VALUES (value1, value2, value3, ...), (value1, value2, value3, ...), ... ``` 其中,column1、column2、column3等是表中的列名,而value1、value2、value3等是要插入数据值。 2. 生成数据:其次,你需要生成要插入数据。可以使用Python、Java等编程语言编写脚本来生成数据。例如,以下是使用Python生成随机数据的示例代码: ``` import random # 生成5万条数据 num_records = 50000 # 生成数据并将其存储在列表中 data = [] for i in range(num_records): column1 = random.randint(1, 100) column2 = random.choice(['foo', 'bar', 'baz']) column3 = random.uniform(0, 1) data.append((column1, column2, column3)) ``` 在这个示例中,我们使用了Python的random模块来生成随机数据。我们首先定义了要生成的数据量(即5万条记录),然后使用循环生成数据并将其存储在一个列表中。最后,我们将数据列表传递给插入语句中的VALUES子句。 3. 执行插入语句:最后,你需要将插入语句发送给MySQL服务器并执行它。可以使用Python的MySQLdb模块或Java的JDBC API等工具来执行插入语句。以下是Python使用MySQLdb模块执行插入语句的示例代码: ``` import MySQLdb # 连接到MySQL服务器 db = MySQLdb.connect(host="localhost", user="root", passwd="password", db="mydatabase") # 创建游标对象 cursor = db.cursor() # 生成数据 # ... # 构建插入语句 insert_stmt = "INSERT INTO mytable (column1, column2, column3) VALUES (%s, %s, %s)" # 执行插入语句 cursor.executemany(insert_stmt, data) # 提交事务 db.commit() # 关闭连接 db.close() ``` 在这个示例中,我们首先使用MySQLdb模块连接到MySQL服务器,并创建一个游标对象。然后,我们生成数据并构建插入语句,使用游标对象的executemany方法将数据插入MySQL中。最后,我们提交事务并关闭连接。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值