//最快的方法 10000记录 23MS
创新互联建站-专业网站定制、快速模板网站建设、高性价比蚌山网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式蚌山网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖蚌山地区。费用合理售后完善,10余年实体公司更值得信赖。
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");
}
建缓冲区。比如其他类型的高速缓存(redis等)作为中间缓冲层。
数据的查询,更改首先在这个层处理,处理完再更新到对应的数据库。
注意额外增加锁,或者缓存机制防止缓存击穿,雪崩导致系统崩溃。
我们经常会遇到操作一张大表,发现操作时间过长或影响在线业务了,想要回退大表操作的场景。在我们停止大表操作之后,等待回滚是一个很漫长的过程,尽管你可能对知道一些缩短时间的方法,处于对生产环境数据完整性的敬畏,也会选择不做介入。最终选择不作为的原因大多源于对操作影响的不确定性。实践出真知,下面针对两种主要提升事务回滚速度的方式进行验证,一种是提升操作可用内存空间,一种是通过停实例,禁用 redo 回滚方式进行进行验证。
仔细阅读过官方手册的同学,一定留意到了对于提升大事务回滚效率,官方提供了两种方法:一是增加 innodb_buffer_pool_size 参数大小,二是合理利用 innodb_force_recovery=3 参数,跳过事务回滚过程。第一种方式比较温和,innodb_buffer_pool_size 参数是可以动态调整的,可行性也较高。第二种方式相较之下较暴力,但效果较好。
两种方式各有自己的优点,第一种方式对线上业务系统影响较小,不会中断在线业务。第二种方式效果更显著,会短暂影响业务连续,回滚所有没有提交的事务。
1.用start transaction关闭mysql的自动提交,合理设置插入批量大小,不要一条数据提交一次。
2.修改表的存储引擎InnoDB为MyISAM。(因为InnoDB中存在redo log日志,每次更新表的结果先写入redo log中,等redo log满了之后再写入磁盘而这个过程是会停止其他所有的事务)
3.优化SQL(一条SQL语句插入多条数据)
4.尽量顺序插入(存储引擎底层采用的数据结构是B+tree索引,如果每次插入记录都在索引的最后面,索引的定位效率很高,并且对索引调整较小;如果插入的记录在索引中间,则需要维护B+tree并且索引定位效率会下降,数据量较大时会有频繁的磁盘操作)